feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

202
smart-app-city/frontend/node_modules/fbjs/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,202 @@
## [3.0.5]
### Fixed
- Upgraded ua-parser-js dependency
## [3.0.4]
### Fixed
- Fixed missing `lib` folder
## [3.0.3]
### Fixed
- Updated cross-fetch to resolve CVE-2022-0235
- Bump copy-props from 2.0.4 to 2.0.5
## [3.0.2]
### Fixed
- Fixed usage of "// @flow weak" in one file to support Flow 0.167
## [3.0.1]
### Fixed
- Upgraded ua-parser-js dependency
## [3.0.0] - 2020-10-07
### Breaking
- Removed `core-js` from `fbjs`. Please use your own Map/Set polyfills in older browsers.
## [2.0.0] - 2020-07-29
### Changed
- Upgraded `core-js` dependency to ^3.6.4
- Replaced `isomorphic-fetch` dependency with `cross-fetch`
### Fixed
- Fixed `__DEV__` check in `invariant`
## [1.0.0] - 2018-09-18
### Added
- More modules, primarily focused on the requirements of Fixed Data Table.
### Removed
- Remove whitelisting of React PropType warning from `warning` module.
- Removed runtime dependency on immutable, reducing package size.
### Changed
- More flow annotations: `joinClasses`, `flatMapArray`
- Upgraded `core-js` dependency to ^2.4.1
### Fixed
- Fixed strict argument arity issues with `Deferred` module.
- `getDocumentScrollElement` now correctly returns the `<html>` element in Chrome 61 instead of `<body>`.
## [0.8.5] - 2016-09-27
### Fixed
- Fixed all remaining issues resulting in Flow errors when `fbjs` is a dependency of a dependency.
### Removed
- Removed now extraneous `flow/lib/Promise.js`.
## [0.8.4] - 2016-08-19
### Changed
- Moved `try/catch` in `warning` module to helper function to prevent deopts.
## [0.8.3] - 2016-05-25
### Added
- `Deferred`: added `Deferred.prototype.catch` to avoid having to call this directly on the Promise.
- `UnicodeUtilsExtra`: added several methods for escaping strings.
### Changed
- More Flow annotations: `containsNode`, `emptyFunction`, `memoizeStringOnly`
- Added explicit `<any>` type arguments to in anticipation of a future Flow change requiring them.
- `Object.assign` calls now replaced with usage of `object-assign` module.
### Fixed
- Type imports in .js.flow files are now properly using relative paths.
- `DataTransfer`: handle Firefox better
## [0.8.2] - 2016-05-05
### Removed
- Removed extraneous production dependency
## [0.8.1] - 2016-04-18
### Added
- We now include a `Promise` class definition in `flow/lib` to account for the changes in Flow v0.23 which removed non-spec methods. This will allow our code to continue typechecking while using these methods.
## [0.8.0] - 2016-04-04
### Added
- Several additional modules. Notably, a collection of Unicode utilities and many new `functional` helpers.
- `CSSCore`: added `matchesSelector` method
### Changed
- Copyright headers updated to reflect current boilerplate
- `@providesModule` headers removed from generated source code
- Flow files now contain relative requires, improving compatibility with Haste and CommonJS module systems
### Fixed
- `isEmpty`: Protect from breaking in environments without `Symbol` defined
## [0.7.2] - 2016-02-05
### Fixed
- `URI`: correctly store reference to value in constructor and return it when stringifying
### Removed
- Backed out rejection tracking for React Native `Promise` implementation. That code now lives in React Native.
## [0.7.1] - 2016-02-02
### Fixed
- Corrected require path issue for native `Promise` module
## [0.7.0] - 2016-01-27
### Added
- `Promise` for React Native with rejection tracking in `__DEV__` and a `finally` method
- `_shouldPolyfillES6Collection`: check if ES6 Collections need to be polyfilled.
### Removed
- `toArray`: removed in favor of using `Array.from` directly.
### Changed
- `ErrorUtils`: Re-uses any global instance that already exists
- `fetch`: Switched to `isomorphic-fetch` when a global implementation is missing
- `shallowEqual`: handles `NaN` values appropriately (as equal), now using `Object.is` semantics
## [0.6.1] - 2016-01-06
### Changed
- `getActiveElement`: no longer throws in non-browser environment (again)
## [0.6.0] - 2015-12-29
### Changed
- Flow: Original source files in `fbjs/flow/include` have been removed in favor of placing original files alongside compiled files in lib with a `.flow` suffix. This requires Flow version 0.19 or greater and a change to `.flowconfig` files to remove the include path.
## [0.5.1] - 2015-12-13
### Added
- `base62` module
## [0.5.0] - 2015-12-04
### Changed
- `getActiveElement`: No longer handles a non-existent `document`
## [0.4.0] - 2015-10-16
### Changed
- `invariant`: Message is no longer prefixed with "Invariant Violation: ".
## [0.3.2] - 2015-10-12
### Added
- Apply appropriate transform (`loose-envify`) when bundling with `browserify`
## [0.3.1] - 2015-10-01
### Fixed
- Ensure the build completes correctly before packaging
## [0.3.0] - 2015-10-01
### Added
- More modules: `memoizeStringOnly`, `joinClasses`
- `UserAgent`: Query information about current user agent
### Changed
- `fetchWithRetries`: Reject failure with an Error, not the response
- `getActiveElement`: no longer throws in non-browser environment

21
smart-app-city/frontend/node_modules/fbjs/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013-present, Facebook, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

46
smart-app-city/frontend/node_modules/fbjs/README.md generated vendored Normal file
View File

@@ -0,0 +1,46 @@
# FBJS
## Purpose
To make it easier for Facebook to share and consume our own JavaScript. Primarily this will allow us to ship code without worrying too much about where it lives, keeping with the spirit of `@providesModule` but working in the broader JavaScript ecosystem.
**Note:** If you are consuming the code here and you are not also a Facebook project, be prepared for a bad time. APIs may appear or disappear and we may not follow semver strictly, though we will do our best to. This library is being published with our use cases in mind and is not necessarily meant to be consumed by the broader public. In order for us to move fast and ship projects like React and Relay, we've made the decision to not support everybody. We probably won't take your feature requests unless they align with our needs. There will be overlap in functionality here and in other open source projects.
## Usage
Any `@providesModule` modules that are used by your project should be added to `src/`. They will be built and added to `module-map.json`. This file will contain a map from `@providesModule` name to what will be published as `fbjs`. The `module-map.json` file can then be consumed in your own project, along with the [rewrite-modules](https://github.com/facebook/fbjs/blob/master/babel-preset/plugins/rewrite-modules.js) Babel plugin (which we'll publish with this), to rewrite requires in your own project. Then, just make sure `fbjs` is a dependency in your `package.json` and your package will consume the shared code.
```js
// Before transform
const emptyFunction = require('emptyFunction');
// After transform
const emptyFunction = require('fbjs/lib/emptyFunction');
```
See React for an example of this. *Coming soon!*
## Building
It's as easy as just running gulp. This assumes you've also done `npm install -g gulp`.
```sh
gulp
```
Alternatively `npm run build` will also work.
### Layout
Right now these packages represent a subset of packages that we use internally at Facebook. Mostly these are support libraries used when shipping larger libraries, like React and Relay, or products. Each of these packages is in its own directory under `src/`.
### Process
Since we use `@providesModule`, we need to rewrite requires to be relative. Thanks to `@providesModule` requiring global uniqueness, we can do this easily. Eventually we'll try to make this part of the process go away by making more projects use CommonJS.
## TODO
- Flow: Ideally we'd ship our original files with type annotations, however that's not doable right now. We have a couple options:
- Make sure our transpilation step converts inline type annotations to the comment format.
- Make our build process also build Flow interface files which we can ship to npm.
- Split into multiple packages. This will be better for more concise versioning, otherwise we'll likely just be shipping lots of major versions.

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
declare var __DEV__: boolean;

10
smart-app-city/frontend/node_modules/fbjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
throw new Error('The fbjs package should not be required without a full path.');

View File

@@ -0,0 +1,41 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var getVendorPrefixedName = require("./getVendorPrefixedName");
var BrowserSupportCore = {
/**
* @return {bool} True if browser supports css animations.
*/
hasCSSAnimations: function hasCSSAnimations() {
return !!getVendorPrefixedName('animationName');
},
/**
* @return {bool} True if browser supports css transforms.
*/
hasCSSTransforms: function hasCSSTransforms() {
return !!getVendorPrefixedName('transform');
},
/**
* @return {bool} True if browser supports css 3d transforms.
*/
hasCSS3DTransforms: function hasCSS3DTransforms() {
return !!getVendorPrefixedName('perspective');
},
/**
* @return {bool} True if browser supports css transitions.
*/
hasCSSTransitions: function hasCSSTransitions() {
return !!getVendorPrefixedName('transition');
}
};
module.exports = BrowserSupportCore;

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule BrowserSupportCore
*/
var getVendorPrefixedName = require("./getVendorPrefixedName");
var BrowserSupportCore = {
/**
* @return {bool} True if browser supports css animations.
*/
hasCSSAnimations: function () {
return !!getVendorPrefixedName('animationName');
},
/**
* @return {bool} True if browser supports css transforms.
*/
hasCSSTransforms: function () {
return !!getVendorPrefixedName('transform');
},
/**
* @return {bool} True if browser supports css 3d transforms.
*/
hasCSS3DTransforms: function () {
return !!getVendorPrefixedName('perspective');
},
/**
* @return {bool} True if browser supports css transitions.
*/
hasCSSTransitions: function () {
return !!getVendorPrefixedName('transition');
}
};
module.exports = BrowserSupportCore;

View File

@@ -0,0 +1,122 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var invariant = require("./invariant");
/**
* The CSSCore module specifies the API (and implements most of the methods)
* that should be used when dealing with the display of elements (via their
* CSS classes and visibility on screen. It is an API focused on mutating the
* display and not reading it as no logical state should be encoded in the
* display of elements.
*/
/* Slow implementation for browsers that don't natively support .matches() */
function matchesSelector_SLOW(element, selector) {
var root = element;
while (root.parentNode) {
root = root.parentNode;
}
var all = root.querySelectorAll(selector);
return Array.prototype.indexOf.call(all, element) !== -1;
}
var CSSCore = {
/**
* Adds the class passed in to the element if it doesn't already have it.
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @return {DOMElement} the element passed in
*/
addClass: function addClass(element, className) {
!!/\s/.test(className) ? process.env.NODE_ENV !== "production" ? invariant(false, 'CSSCore.addClass takes only a single class name. "%s" contains ' + 'multiple classes.', className) : invariant(false) : void 0;
if (className) {
if (element.classList) {
element.classList.add(className);
} else if (!CSSCore.hasClass(element, className)) {
element.className = element.className + ' ' + className;
}
}
return element;
},
/**
* Removes the class passed in from the element
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @return {DOMElement} the element passed in
*/
removeClass: function removeClass(element, className) {
!!/\s/.test(className) ? process.env.NODE_ENV !== "production" ? invariant(false, 'CSSCore.removeClass takes only a single class name. "%s" contains ' + 'multiple classes.', className) : invariant(false) : void 0;
if (className) {
if (element.classList) {
element.classList.remove(className);
} else if (CSSCore.hasClass(element, className)) {
element.className = element.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1').replace(/\s+/g, ' ') // multiple spaces to one
.replace(/^\s*|\s*$/g, ''); // trim the ends
}
}
return element;
},
/**
* Helper to add or remove a class from an element based on a condition.
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @param {*} bool condition to whether to add or remove the class
* @return {DOMElement} the element passed in
*/
conditionClass: function conditionClass(element, className, bool) {
return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className);
},
/**
* Tests whether the element has the class specified.
*
* @param {DOMNode|DOMWindow} element the element to check the class on
* @param {string} className the CSS className
* @return {boolean} true if the element has the class, false if not
*/
hasClass: function hasClass(element, className) {
!!/\s/.test(className) ? process.env.NODE_ENV !== "production" ? invariant(false, 'CSS.hasClass takes only a single class name.') : invariant(false) : void 0;
if (element.classList) {
return !!className && element.classList.contains(className);
}
return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1;
},
/**
* Tests whether the element matches the selector specified
*
* @param {DOMNode|DOMWindow} element the element that we are querying
* @param {string} selector the CSS selector
* @return {boolean} true if the element matches the selector, false if not
*/
matchesSelector: function matchesSelector(element, selector) {
var matchesImpl = element.matches || element.webkitMatchesSelector || element.mozMatchesSelector || element.msMatchesSelector || function (s) {
return matchesSelector_SLOW(element, s);
};
return matchesImpl.call(element, selector);
}
};
module.exports = CSSCore;

View File

@@ -0,0 +1,119 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule CSSCore
* @typechecks
*/
const invariant = require("./invariant");
/**
* The CSSCore module specifies the API (and implements most of the methods)
* that should be used when dealing with the display of elements (via their
* CSS classes and visibility on screen. It is an API focused on mutating the
* display and not reading it as no logical state should be encoded in the
* display of elements.
*/
/* Slow implementation for browsers that don't natively support .matches() */
function matchesSelector_SLOW(element, selector) {
let root = element;
while (root.parentNode) {
root = root.parentNode;
}
const all = root.querySelectorAll(selector);
return Array.prototype.indexOf.call(all, element) !== -1;
}
const CSSCore = {
/**
* Adds the class passed in to the element if it doesn't already have it.
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @return {DOMElement} the element passed in
*/
addClass: function (element, className) {
invariant(!/\s/.test(className), 'CSSCore.addClass takes only a single class name. "%s" contains ' + 'multiple classes.', className);
if (className) {
if (element.classList) {
element.classList.add(className);
} else if (!CSSCore.hasClass(element, className)) {
element.className = element.className + ' ' + className;
}
}
return element;
},
/**
* Removes the class passed in from the element
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @return {DOMElement} the element passed in
*/
removeClass: function (element, className) {
invariant(!/\s/.test(className), 'CSSCore.removeClass takes only a single class name. "%s" contains ' + 'multiple classes.', className);
if (className) {
if (element.classList) {
element.classList.remove(className);
} else if (CSSCore.hasClass(element, className)) {
element.className = element.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1').replace(/\s+/g, ' ') // multiple spaces to one
.replace(/^\s*|\s*$/g, ''); // trim the ends
}
}
return element;
},
/**
* Helper to add or remove a class from an element based on a condition.
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @param {*} bool condition to whether to add or remove the class
* @return {DOMElement} the element passed in
*/
conditionClass: function (element, className, bool) {
return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className);
},
/**
* Tests whether the element has the class specified.
*
* @param {DOMNode|DOMWindow} element the element to check the class on
* @param {string} className the CSS className
* @return {boolean} true if the element has the class, false if not
*/
hasClass: function (element, className) {
invariant(!/\s/.test(className), 'CSS.hasClass takes only a single class name.');
if (element.classList) {
return !!className && element.classList.contains(className);
}
return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1;
},
/**
* Tests whether the element matches the selector specified
*
* @param {DOMNode|DOMWindow} element the element that we are querying
* @param {string} selector the CSS selector
* @return {boolean} true if the element matches the selector, false if not
*/
matchesSelector: function (element, selector) {
const matchesImpl = element.matches || element.webkitMatchesSelector || element.mozMatchesSelector || element.msMatchesSelector || (s => matchesSelector_SLOW(element, s));
return matchesImpl.call(element, selector);
}
};
module.exports = CSSCore;

View File

@@ -0,0 +1,47 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var invariant = require("./invariant");
var CircularBuffer = /*#__PURE__*/function () {
function CircularBuffer(size) {
!(size > 0) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Buffer size should be a positive integer') : invariant(false) : void 0;
this._size = size;
this._head = 0;
this._buffer = [];
}
var _proto = CircularBuffer.prototype;
_proto.write = function write(entry) {
if (this._buffer.length < this._size) {
this._buffer.push(entry);
} else {
this._buffer[this._head] = entry;
this._head++;
this._head %= this._size;
}
return this;
};
_proto.read = function read() {
return this._buffer.slice(this._head).concat(this._buffer.slice(0, this._head));
};
_proto.clear = function clear() {
this._head = 0;
this._buffer = [];
return this;
};
return CircularBuffer;
}();
module.exports = CircularBuffer;

View File

@@ -0,0 +1,43 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule CircularBuffer
*/
var invariant = require("./invariant");
class CircularBuffer {
constructor(size) {
invariant(size > 0, 'Buffer size should be a positive integer');
this._size = size;
this._head = 0;
this._buffer = [];
}
write(entry) {
if (this._buffer.length < this._size) {
this._buffer.push(entry);
} else {
this._buffer[this._head] = entry;
this._head++;
this._head %= this._size;
}
return this;
}
read() {
return this._buffer.slice(this._head).concat(this._buffer.slice(0, this._head));
}
clear() {
this._head = 0;
this._buffer = [];
return this;
}
}
module.exports = CircularBuffer;

View File

@@ -0,0 +1,158 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* This class listens to events on the document and then updates a react
* component through callbacks.
* Please note that captureMouseMove must be called in
* order to initialize listeners on mousemove and mouseup.
* releaseMouseMove must be called to remove them. It is important to
* call releaseMouseMoves since mousemove is expensive to listen to.
*
* @typechecks
*/
'use strict';
var EventListener = require("./EventListener");
var cancelAnimationFramePolyfill = require("./cancelAnimationFramePolyfill");
var requestAnimationFramePolyfill = require("./requestAnimationFramePolyfill");
var DOMMouseMoveTracker = /*#__PURE__*/function () {
/**
* onMove is the callback that will be called on every mouse move.
* onMoveEnd is called on mouse up when movement has ended.
*/
function DOMMouseMoveTracker(
/*function*/
onMove,
/*function*/
onMoveEnd,
/*DOMElement*/
domNode) {
this._isDragging = false;
this._animationFrameID = null;
this._domNode = domNode;
this._onMove = onMove;
this._onMoveEnd = onMoveEnd;
this._onMouseMove = this._onMouseMove.bind(this);
this._onMouseUp = this._onMouseUp.bind(this);
this._didMouseMove = this._didMouseMove.bind(this);
}
/**
* This is to set up the listeners for listening to mouse move
* and mouse up signaling the movement has ended. Please note that these
* listeners are added at the document.body level. It takes in an event
* in order to grab inital state.
*/
var _proto = DOMMouseMoveTracker.prototype;
_proto.captureMouseMoves = function captureMouseMoves(
/*object*/
event) {
if (!this._eventMoveToken && !this._eventUpToken) {
this._eventMoveToken = EventListener.listen(this._domNode, 'mousemove', this._onMouseMove);
this._eventUpToken = EventListener.listen(this._domNode, 'mouseup', this._onMouseUp);
}
if (!this._isDragging) {
this._deltaX = 0;
this._deltaY = 0;
this._isDragging = true;
this._x = event.clientX;
this._y = event.clientY;
}
event.preventDefault();
};
/**
* These releases all of the listeners on document.body.
*/
_proto.releaseMouseMoves = function releaseMouseMoves() {
if (this._eventMoveToken && this._eventUpToken) {
this._eventMoveToken.remove();
this._eventMoveToken = null;
this._eventUpToken.remove();
this._eventUpToken = null;
}
if (this._animationFrameID !== null) {
cancelAnimationFramePolyfill(this._animationFrameID);
this._animationFrameID = null;
}
if (this._isDragging) {
this._isDragging = false;
this._x = null;
this._y = null;
}
};
/**
* Returns whether or not if the mouse movement is being tracked.
*/
_proto.isDragging = function isDragging()
/*boolean*/
{
return this._isDragging;
};
/**
* Calls onMove passed into constructor and updates internal state.
*/
_proto._onMouseMove = function _onMouseMove(
/*object*/
event) {
var x = event.clientX;
var y = event.clientY;
this._deltaX += x - this._x;
this._deltaY += y - this._y;
if (this._animationFrameID === null) {
// The mouse may move faster then the animation frame does.
// Use `requestAnimationFramePolyfill` to avoid over-updating.
this._animationFrameID = requestAnimationFramePolyfill(this._didMouseMove);
}
this._x = x;
this._y = y;
event.preventDefault();
};
_proto._didMouseMove = function _didMouseMove() {
this._animationFrameID = null;
this._onMove(this._deltaX, this._deltaY);
this._deltaX = 0;
this._deltaY = 0;
};
/**
* Calls onMoveEnd passed into constructor and updates internal state.
*/
_proto._onMouseUp = function _onMouseUp() {
if (this._animationFrameID) {
this._didMouseMove();
}
this._onMoveEnd();
};
return DOMMouseMoveTracker;
}();
module.exports = DOMMouseMoveTracker;

View File

@@ -0,0 +1,156 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* This class listens to events on the document and then updates a react
* component through callbacks.
* Please note that captureMouseMove must be called in
* order to initialize listeners on mousemove and mouseup.
* releaseMouseMove must be called to remove them. It is important to
* call releaseMouseMoves since mousemove is expensive to listen to.
*
* @providesModule DOMMouseMoveTracker
* @typechecks
*/
'use strict';
const EventListener = require("./EventListener");
const cancelAnimationFramePolyfill = require("./cancelAnimationFramePolyfill");
const requestAnimationFramePolyfill = require("./requestAnimationFramePolyfill");
class DOMMouseMoveTracker {
/**
* onMove is the callback that will be called on every mouse move.
* onMoveEnd is called on mouse up when movement has ended.
*/
constructor(
/*function*/
onMove,
/*function*/
onMoveEnd,
/*DOMElement*/
domNode) {
this._isDragging = false;
this._animationFrameID = null;
this._domNode = domNode;
this._onMove = onMove;
this._onMoveEnd = onMoveEnd;
this._onMouseMove = this._onMouseMove.bind(this);
this._onMouseUp = this._onMouseUp.bind(this);
this._didMouseMove = this._didMouseMove.bind(this);
}
/**
* This is to set up the listeners for listening to mouse move
* and mouse up signaling the movement has ended. Please note that these
* listeners are added at the document.body level. It takes in an event
* in order to grab inital state.
*/
captureMouseMoves(
/*object*/
event) {
if (!this._eventMoveToken && !this._eventUpToken) {
this._eventMoveToken = EventListener.listen(this._domNode, 'mousemove', this._onMouseMove);
this._eventUpToken = EventListener.listen(this._domNode, 'mouseup', this._onMouseUp);
}
if (!this._isDragging) {
this._deltaX = 0;
this._deltaY = 0;
this._isDragging = true;
this._x = event.clientX;
this._y = event.clientY;
}
event.preventDefault();
}
/**
* These releases all of the listeners on document.body.
*/
releaseMouseMoves() {
if (this._eventMoveToken && this._eventUpToken) {
this._eventMoveToken.remove();
this._eventMoveToken = null;
this._eventUpToken.remove();
this._eventUpToken = null;
}
if (this._animationFrameID !== null) {
cancelAnimationFramePolyfill(this._animationFrameID);
this._animationFrameID = null;
}
if (this._isDragging) {
this._isDragging = false;
this._x = null;
this._y = null;
}
}
/**
* Returns whether or not if the mouse movement is being tracked.
*/
isDragging()
/*boolean*/
{
return this._isDragging;
}
/**
* Calls onMove passed into constructor and updates internal state.
*/
_onMouseMove(
/*object*/
event) {
const x = event.clientX;
const y = event.clientY;
this._deltaX += x - this._x;
this._deltaY += y - this._y;
if (this._animationFrameID === null) {
// The mouse may move faster then the animation frame does.
// Use `requestAnimationFramePolyfill` to avoid over-updating.
this._animationFrameID = requestAnimationFramePolyfill(this._didMouseMove);
}
this._x = x;
this._y = y;
event.preventDefault();
}
_didMouseMove() {
this._animationFrameID = null;
this._onMove(this._deltaX, this._deltaY);
this._deltaX = 0;
this._deltaY = 0;
}
/**
* Calls onMoveEnd passed into constructor and updates internal state.
*/
_onMouseUp() {
if (this._animationFrameID) {
this._didMouseMove();
}
this._onMoveEnd();
}
}
module.exports = DOMMouseMoveTracker;

View File

@@ -0,0 +1,213 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var PhotosMimeType = require("./PhotosMimeType");
var createArrayFromMixed = require("./createArrayFromMixed");
var emptyFunction = require("./emptyFunction");
var CR_LF_REGEX = new RegExp("\r\n", 'g');
var LF_ONLY = "\n";
var RICH_TEXT_TYPES = {
'text/rtf': 1,
'text/html': 1
};
/**
* If DataTransferItem is a file then return the Blob of data.
*
* @param {object} item
* @return {?blob}
*/
function getFileFromDataTransfer(item) {
if (item.kind == 'file') {
return item.getAsFile();
}
}
var DataTransfer = /*#__PURE__*/function () {
/**
* @param {object} data
*/
function DataTransfer(data) {
this.data = data; // Types could be DOMStringList or array
this.types = data.types ? createArrayFromMixed(data.types) : [];
}
/**
* Is this likely to be a rich text data transfer?
*
* @return {boolean}
*/
var _proto = DataTransfer.prototype;
_proto.isRichText = function isRichText() {
// If HTML is available, treat this data as rich text. This way, we avoid
// using a pasted image if it is packaged with HTML -- this may occur with
// pastes from MS Word, for example. However this is only rich text if
// there's accompanying text.
if (this.getHTML() && this.getText()) {
return true;
} // When an image is copied from a preview window, you end up with two
// DataTransferItems one of which is a file's metadata as text. Skip those.
if (this.isImage()) {
return false;
}
return this.types.some(function (type) {
return RICH_TEXT_TYPES[type];
});
};
/**
* Get raw text.
*
* @return {?string}
*/
_proto.getText = function getText() {
var text;
if (this.data.getData) {
if (!this.types.length) {
text = this.data.getData('Text');
} else if (this.types.indexOf('text/plain') != -1) {
text = this.data.getData('text/plain');
}
}
return text ? text.replace(CR_LF_REGEX, LF_ONLY) : null;
};
/**
* Get HTML paste data
*
* @return {?string}
*/
_proto.getHTML = function getHTML() {
if (this.data.getData) {
if (!this.types.length) {
return this.data.getData('Text');
} else if (this.types.indexOf('text/html') != -1) {
return this.data.getData('text/html');
}
}
};
/**
* Is this a link data transfer?
*
* @return {boolean}
*/
_proto.isLink = function isLink() {
return this.types.some(function (type) {
return type.indexOf('Url') != -1 || type.indexOf('text/uri-list') != -1 || type.indexOf('text/x-moz-url');
});
};
/**
* Get a link url.
*
* @return {?string}
*/
_proto.getLink = function getLink() {
if (this.data.getData) {
if (this.types.indexOf('text/x-moz-url') != -1) {
var url = this.data.getData('text/x-moz-url').split('\n');
return url[0];
}
return this.types.indexOf('text/uri-list') != -1 ? this.data.getData('text/uri-list') : this.data.getData('url');
}
return null;
};
/**
* Is this an image data transfer?
*
* @return {boolean}
*/
_proto.isImage = function isImage() {
var isImage = this.types.some(function (type) {
// Firefox will have a type of application/x-moz-file for images during
// dragging
return type.indexOf('application/x-moz-file') != -1;
});
if (isImage) {
return true;
}
var items = this.getFiles();
for (var i = 0; i < items.length; i++) {
var type = items[i].type;
if (!PhotosMimeType.isImage(type)) {
return false;
}
}
return true;
};
_proto.getCount = function getCount() {
if (this.data.hasOwnProperty('items')) {
return this.data.items.length;
} else if (this.data.hasOwnProperty('mozItemCount')) {
return this.data.mozItemCount;
} else if (this.data.files) {
return this.data.files.length;
}
return null;
};
/**
* Get files.
*
* @return {array}
*/
_proto.getFiles = function getFiles() {
if (this.data.items) {
// createArrayFromMixed doesn't properly handle DataTransferItemLists.
return Array.prototype.slice.call(this.data.items).map(getFileFromDataTransfer).filter(emptyFunction.thatReturnsArgument);
} else if (this.data.files) {
return Array.prototype.slice.call(this.data.files);
} else {
return [];
}
};
/**
* Are there any files to fetch?
*
* @return {boolean}
*/
_proto.hasFiles = function hasFiles() {
return this.getFiles().length > 0;
};
return DataTransfer;
}();
module.exports = DataTransfer;

View File

@@ -0,0 +1,207 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule DataTransfer
* @typechecks
*/
var PhotosMimeType = require("./PhotosMimeType");
var createArrayFromMixed = require("./createArrayFromMixed");
var emptyFunction = require("./emptyFunction");
var CR_LF_REGEX = new RegExp('\u000D\u000A', 'g');
var LF_ONLY = '\u000A';
var RICH_TEXT_TYPES = {
'text/rtf': 1,
'text/html': 1
};
/**
* If DataTransferItem is a file then return the Blob of data.
*
* @param {object} item
* @return {?blob}
*/
function getFileFromDataTransfer(item) {
if (item.kind == 'file') {
return item.getAsFile();
}
}
class DataTransfer {
/**
* @param {object} data
*/
constructor(data) {
this.data = data; // Types could be DOMStringList or array
this.types = data.types ? createArrayFromMixed(data.types) : [];
}
/**
* Is this likely to be a rich text data transfer?
*
* @return {boolean}
*/
isRichText() {
// If HTML is available, treat this data as rich text. This way, we avoid
// using a pasted image if it is packaged with HTML -- this may occur with
// pastes from MS Word, for example. However this is only rich text if
// there's accompanying text.
if (this.getHTML() && this.getText()) {
return true;
} // When an image is copied from a preview window, you end up with two
// DataTransferItems one of which is a file's metadata as text. Skip those.
if (this.isImage()) {
return false;
}
return this.types.some(type => RICH_TEXT_TYPES[type]);
}
/**
* Get raw text.
*
* @return {?string}
*/
getText() {
var text;
if (this.data.getData) {
if (!this.types.length) {
text = this.data.getData('Text');
} else if (this.types.indexOf('text/plain') != -1) {
text = this.data.getData('text/plain');
}
}
return text ? text.replace(CR_LF_REGEX, LF_ONLY) : null;
}
/**
* Get HTML paste data
*
* @return {?string}
*/
getHTML() {
if (this.data.getData) {
if (!this.types.length) {
return this.data.getData('Text');
} else if (this.types.indexOf('text/html') != -1) {
return this.data.getData('text/html');
}
}
}
/**
* Is this a link data transfer?
*
* @return {boolean}
*/
isLink() {
return this.types.some(type => {
return type.indexOf('Url') != -1 || type.indexOf('text/uri-list') != -1 || type.indexOf('text/x-moz-url');
});
}
/**
* Get a link url.
*
* @return {?string}
*/
getLink() {
if (this.data.getData) {
if (this.types.indexOf('text/x-moz-url') != -1) {
let url = this.data.getData('text/x-moz-url').split('\n');
return url[0];
}
return this.types.indexOf('text/uri-list') != -1 ? this.data.getData('text/uri-list') : this.data.getData('url');
}
return null;
}
/**
* Is this an image data transfer?
*
* @return {boolean}
*/
isImage() {
var isImage = this.types.some(type => {
// Firefox will have a type of application/x-moz-file for images during
// dragging
return type.indexOf('application/x-moz-file') != -1;
});
if (isImage) {
return true;
}
var items = this.getFiles();
for (var i = 0; i < items.length; i++) {
var type = items[i].type;
if (!PhotosMimeType.isImage(type)) {
return false;
}
}
return true;
}
getCount() {
if (this.data.hasOwnProperty('items')) {
return this.data.items.length;
} else if (this.data.hasOwnProperty('mozItemCount')) {
return this.data.mozItemCount;
} else if (this.data.files) {
return this.data.files.length;
}
return null;
}
/**
* Get files.
*
* @return {array}
*/
getFiles() {
if (this.data.items) {
// createArrayFromMixed doesn't properly handle DataTransferItemLists.
return Array.prototype.slice.call(this.data.items).map(getFileFromDataTransfer).filter(emptyFunction.thatReturnsArgument);
} else if (this.data.files) {
return Array.prototype.slice.call(this.data.files);
} else {
return [];
}
}
/**
* Are there any files to fetch?
*
* @return {boolean}
*/
hasFiles() {
return this.getFiles().length > 0;
}
}
module.exports = DataTransfer;

View File

@@ -0,0 +1,89 @@
"use strict";
var Promise = require("./Promise");
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*
*/
/**
* Deferred provides a Promise-like API that exposes methods to resolve and
* reject the Promise. It is most useful when converting non-Promise code to use
* Promises.
*
* If you want to export the Promise without exposing access to the resolve and
* reject methods, you should export `getPromise` which returns a Promise with
* the same semantics excluding those methods.
*/
var Deferred = /*#__PURE__*/function () {
function Deferred() {
var _this = this;
_defineProperty(this, "_settled", void 0);
_defineProperty(this, "_promise", void 0);
_defineProperty(this, "_resolve", void 0);
_defineProperty(this, "_reject", void 0);
this._settled = false;
this._promise = new Promise(function (resolve, reject) {
_this._resolve = resolve;
_this._reject = reject;
});
}
var _proto = Deferred.prototype;
_proto.getPromise = function getPromise() {
return this._promise;
};
_proto.resolve = function resolve(value) {
this._settled = true;
this._resolve(value);
};
_proto.reject = function reject(reason) {
this._settled = true;
this._reject(reason);
};
_proto["catch"] = function _catch(onReject) {
return Promise.prototype["catch"].apply(this._promise, arguments);
};
_proto.then = function then(onFulfill, onReject) {
return Promise.prototype.then.apply(this._promise, arguments);
};
_proto.done = function done(onFulfill, onReject) {
// Embed the polyfill for the non-standard Promise.prototype.done so that
// users of the open source fbjs don't need a custom lib for Promise
var promise = arguments.length ? this._promise.then.apply(this._promise, arguments) : this._promise;
promise.then(undefined, function (err) {
setTimeout(function () {
throw err;
}, 0);
});
};
_proto.isSettled = function isSettled() {
return this._settled;
};
return Deferred;
}();
module.exports = Deferred;

View File

@@ -0,0 +1,76 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Deferred
* @typechecks
* @flow
*/
/**
* Deferred provides a Promise-like API that exposes methods to resolve and
* reject the Promise. It is most useful when converting non-Promise code to use
* Promises.
*
* If you want to export the Promise without exposing access to the resolve and
* reject methods, you should export `getPromise` which returns a Promise with
* the same semantics excluding those methods.
*/
class Deferred<Tvalue, Treason> {
_settled: boolean;
_promise: Promise<any>;
_resolve: (value: Tvalue) => void;
_reject: (reason: Treason) => void;
constructor() {
this._settled = false;
this._promise = new Promise((resolve, reject) => {
this._resolve = (resolve: any);
this._reject = (reject: any);
});
}
getPromise(): Promise<any> {
return this._promise;
}
resolve(value: Tvalue): void {
this._settled = true;
this._resolve(value);
}
reject(reason: Treason): void {
this._settled = true;
this._reject(reason);
}
catch(onReject?: ?(error: any) => mixed): Promise<any> {
return Promise.prototype.catch.apply(this._promise, arguments);
}
then(onFulfill?: ?(value: any) => mixed, onReject?: ?(error: any) => mixed): Promise<any> {
return Promise.prototype.then.apply(this._promise, arguments);
}
done(onFulfill?: ?(value: any) => mixed, onReject?: ?(error: any) => mixed): void {
// Embed the polyfill for the non-standard Promise.prototype.done so that
// users of the open source fbjs don't need a custom lib for Promise
const promise = arguments.length ? this._promise.then.apply(this._promise, arguments) : this._promise;
promise.then(undefined, function (err) {
setTimeout(function () {
throw err;
}, 0);
});
}
isSettled(): boolean {
return this._settled;
}
}
module.exports = Deferred;

View File

@@ -0,0 +1,24 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/* jslint unused:false */
if (global.ErrorUtils) {
module.exports = global.ErrorUtils;
} else {
var ErrorUtils = {
applyWithGuard: function applyWithGuard(callback, context, args, onError, name) {
return callback.apply(context, args);
},
guard: function guard(callback, name) {
return callback;
}
};
module.exports = ErrorUtils;
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule ErrorUtils
*/
/* jslint unused:false */
if (global.ErrorUtils) {
module.exports = global.ErrorUtils;
} else {
var ErrorUtils = {
applyWithGuard(callback, context, args, onError, name) {
return callback.apply(context, args);
},
guard(callback, name) {
return callback;
}
};
module.exports = ErrorUtils;
}

View File

@@ -0,0 +1,73 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var emptyFunction = require("./emptyFunction");
/**
* Upstream version of event listener. Does not take into account specific
* nature of platform.
*/
var EventListener = {
/**
* Listen to DOM events during the bubble phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
listen: function listen(target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, false);
return {
remove: function remove() {
target.removeEventListener(eventType, callback, false);
}
};
} else if (target.attachEvent) {
target.attachEvent('on' + eventType, callback);
return {
remove: function remove() {
target.detachEvent('on' + eventType, callback);
}
};
}
},
/**
* Listen to DOM events during the capture phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
capture: function capture(target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, true);
return {
remove: function remove() {
target.removeEventListener(eventType, callback, true);
}
};
} else {
if (process.env.NODE_ENV !== "production") {
console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.');
}
return {
remove: emptyFunction
};
}
},
registerDefault: function registerDefault() {}
};
module.exports = EventListener;

View File

@@ -0,0 +1,74 @@
declare var __DEV__: boolean;
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule EventListener
* @typechecks
*/
var emptyFunction = require("./emptyFunction");
/**
* Upstream version of event listener. Does not take into account specific
* nature of platform.
*/
var EventListener = {
/**
* Listen to DOM events during the bubble phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
listen: function (target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, false);
return {
remove: function () {
target.removeEventListener(eventType, callback, false);
}
};
} else if (target.attachEvent) {
target.attachEvent('on' + eventType, callback);
return {
remove: function () {
target.detachEvent('on' + eventType, callback);
}
};
}
},
/**
* Listen to DOM events during the capture phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
capture: function (target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, true);
return {
remove: function () {
target.removeEventListener(eventType, callback, true);
}
};
} else {
if (__DEV__) {
console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.');
}
return {
remove: emptyFunction
};
}
},
registerDefault: function () {}
};
module.exports = EventListener;

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use strict';
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
/**
* Simple, lightweight module assisting with the detection and context of
* Worker. Helps avoid circular dependencies and allows code to reason about
* whether or not they are in a Worker, even if they never include the main
* `ReactWorker` dependency.
*/
var ExecutionEnvironment = {
canUseDOM: canUseDOM,
canUseWorkers: typeof Worker !== 'undefined',
canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),
canUseViewport: canUseDOM && !!window.screen,
isInWorker: !canUseDOM // For now, this is true - might change in the future.
};
module.exports = ExecutionEnvironment;

View File

@@ -0,0 +1,27 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule ExecutionEnvironment
*/
'use strict';
const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
/**
* Simple, lightweight module assisting with the detection and context of
* Worker. Helps avoid circular dependencies and allows code to reason about
* whether or not they are in a Worker, even if they never include the main
* `ReactWorker` dependency.
*/
const ExecutionEnvironment = {
canUseDOM: canUseDOM,
canUseWorkers: typeof Worker !== 'undefined',
canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),
canUseViewport: canUseDOM && !!window.screen,
isInWorker: !canUseDOM // For now, this is true - might change in the future.
};
module.exports = ExecutionEnvironment;

166
smart-app-city/frontend/node_modules/fbjs/lib/Heap.js generated vendored Normal file
View File

@@ -0,0 +1,166 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
* @preventMunge
*/
'use strict';
/*
* @param {*} a
* @param {*} b
* @return {boolean}
*/
function defaultComparator(a, b) {
return a < b;
}
var Heap = /*#__PURE__*/function () {
function Heap(items, comparator) {
this._items = items || [];
this._size = this._items.length;
this._comparator = comparator || defaultComparator;
this._heapify();
}
/*
* @return {boolean}
*/
var _proto = Heap.prototype;
_proto.empty = function empty() {
return this._size === 0;
};
/*
* @return {*}
*/
_proto.pop = function pop() {
if (this._size === 0) {
return;
}
var elt = this._items[0];
var lastElt = this._items.pop();
this._size--;
if (this._size > 0) {
this._items[0] = lastElt;
this._sinkDown(0);
}
return elt;
};
/*
* @param {*} item
*/
_proto.push = function push(item) {
this._items[this._size++] = item;
this._bubbleUp(this._size - 1);
};
/*
* @return {number}
*/
_proto.size = function size() {
return this._size;
};
/*
* @return {*}
*/
_proto.peek = function peek() {
if (this._size === 0) {
return;
}
return this._items[0];
};
_proto._heapify = function _heapify() {
for (var index = Math.floor((this._size + 1) / 2); index >= 0; index--) {
this._sinkDown(index);
}
};
/*
* @parent {number} index
*/
_proto._bubbleUp = function _bubbleUp(index) {
var elt = this._items[index];
while (index > 0) {
var parentIndex = Math.floor((index + 1) / 2) - 1;
var parentElt = this._items[parentIndex]; // if parentElt < elt, stop
if (this._comparator(parentElt, elt)) {
return;
} // swap
this._items[parentIndex] = elt;
this._items[index] = parentElt;
index = parentIndex;
}
};
/*
* @parent {number} index
*/
_proto._sinkDown = function _sinkDown(index) {
var elt = this._items[index];
while (true) {
var leftChildIndex = 2 * (index + 1) - 1;
var rightChildIndex = 2 * (index + 1);
var swapIndex = -1;
if (leftChildIndex < this._size) {
var leftChild = this._items[leftChildIndex];
if (this._comparator(leftChild, elt)) {
swapIndex = leftChildIndex;
}
}
if (rightChildIndex < this._size) {
var rightChild = this._items[rightChildIndex];
if (this._comparator(rightChild, elt)) {
if (swapIndex === -1 || this._comparator(rightChild, this._items[swapIndex])) {
swapIndex = rightChildIndex;
}
}
} // if we don't have a swap, stop
if (swapIndex === -1) {
return;
}
this._items[index] = this._items[swapIndex];
this._items[swapIndex] = elt;
index = swapIndex;
}
};
return Heap;
}();
module.exports = Heap;

View File

@@ -0,0 +1,164 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Heap
* @typechecks
* @preventMunge
*/
'use strict';
/*
* @param {*} a
* @param {*} b
* @return {boolean}
*/
function defaultComparator(a, b) {
return a < b;
}
class Heap {
constructor(items, comparator) {
this._items = items || [];
this._size = this._items.length;
this._comparator = comparator || defaultComparator;
this._heapify();
}
/*
* @return {boolean}
*/
empty() {
return this._size === 0;
}
/*
* @return {*}
*/
pop() {
if (this._size === 0) {
return;
}
const elt = this._items[0];
const lastElt = this._items.pop();
this._size--;
if (this._size > 0) {
this._items[0] = lastElt;
this._sinkDown(0);
}
return elt;
}
/*
* @param {*} item
*/
push(item) {
this._items[this._size++] = item;
this._bubbleUp(this._size - 1);
}
/*
* @return {number}
*/
size() {
return this._size;
}
/*
* @return {*}
*/
peek() {
if (this._size === 0) {
return;
}
return this._items[0];
}
_heapify() {
for (let index = Math.floor((this._size + 1) / 2); index >= 0; index--) {
this._sinkDown(index);
}
}
/*
* @parent {number} index
*/
_bubbleUp(index) {
const elt = this._items[index];
while (index > 0) {
const parentIndex = Math.floor((index + 1) / 2) - 1;
const parentElt = this._items[parentIndex]; // if parentElt < elt, stop
if (this._comparator(parentElt, elt)) {
return;
} // swap
this._items[parentIndex] = elt;
this._items[index] = parentElt;
index = parentIndex;
}
}
/*
* @parent {number} index
*/
_sinkDown(index) {
const elt = this._items[index];
while (true) {
const leftChildIndex = 2 * (index + 1) - 1;
const rightChildIndex = 2 * (index + 1);
let swapIndex = -1;
if (leftChildIndex < this._size) {
const leftChild = this._items[leftChildIndex];
if (this._comparator(leftChild, elt)) {
swapIndex = leftChildIndex;
}
}
if (rightChildIndex < this._size) {
const rightChild = this._items[rightChildIndex];
if (this._comparator(rightChild, elt)) {
if (swapIndex === -1 || this._comparator(rightChild, this._items[swapIndex])) {
swapIndex = rightChildIndex;
}
}
} // if we don't have a swap, stop
if (swapIndex === -1) {
return;
}
this._items[index] = this._items[swapIndex];
this._items[swapIndex] = elt;
index = swapIndex;
}
}
}
module.exports = Heap;

View File

@@ -0,0 +1,208 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
'use strict';
var Heap = require("./Heap");
var invariant = require("./invariant"); // Data structure that allows to store values and assign positions to them
// in a way to minimize changing positions of stored values when new ones are
// added or when some values are replaced. Stored elements are alwasy assigned
// a consecutive set of positoins startin from 0 up to count of elements less 1
// Following actions can be executed
// * get position assigned to given value (null if value is not stored)
// * create new entry for new value and get assigned position back
// * replace value that is furthest from specified value range with new value
// and get it's position back
// All operations take amortized log(n) time where n is number of elements in
// the set.
var IntegerBufferSet = /*#__PURE__*/function () {
function IntegerBufferSet() {
this._valueToPositionMap = {};
this._size = 0;
this._smallValues = new Heap([], // Initial data in the heap
this._smallerComparator);
this._largeValues = new Heap([], // Initial data in the heap
this._greaterComparator);
this.getNewPositionForValue = this.getNewPositionForValue.bind(this);
this.getValuePosition = this.getValuePosition.bind(this);
this.getSize = this.getSize.bind(this);
this.replaceFurthestValuePosition = this.replaceFurthestValuePosition.bind(this);
}
var _proto = IntegerBufferSet.prototype;
_proto.getSize = function getSize()
/*number*/
{
return this._size;
};
_proto.getValuePosition = function getValuePosition(
/*number*/
value)
/*?number*/
{
if (this._valueToPositionMap[value] === undefined) {
return null;
}
return this._valueToPositionMap[value];
};
_proto.getNewPositionForValue = function getNewPositionForValue(
/*number*/
value)
/*number*/
{
!(this._valueToPositionMap[value] === undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, "Shouldn't try to find new position for value already stored in BufferSet") : invariant(false) : void 0;
var newPosition = this._size;
this._size++;
this._pushToHeaps(newPosition, value);
this._valueToPositionMap[value] = newPosition;
return newPosition;
};
_proto.replaceFurthestValuePosition = function replaceFurthestValuePosition(
/*number*/
lowValue,
/*number*/
highValue,
/*number*/
newValue)
/*?number*/
{
!(this._valueToPositionMap[newValue] === undefined) ? process.env.NODE_ENV !== "production" ? invariant(false, "Shouldn't try to replace values with value already stored value in " + "BufferSet") : invariant(false) : void 0;
this._cleanHeaps();
if (this._smallValues.empty() || this._largeValues.empty()) {
// Threre are currently no values stored. We will have to create new
// position for this value.
return null;
}
var minValue = this._smallValues.peek().value;
var maxValue = this._largeValues.peek().value;
if (minValue >= lowValue && maxValue <= highValue) {
// All values currently stored are necessary, we can't reuse any of them.
return null;
}
var valueToReplace;
if (lowValue - minValue > maxValue - highValue) {
// minValue is further from provided range. We will reuse it's position.
valueToReplace = minValue;
this._smallValues.pop();
} else {
valueToReplace = maxValue;
this._largeValues.pop();
}
var position = this._valueToPositionMap[valueToReplace];
delete this._valueToPositionMap[valueToReplace];
this._valueToPositionMap[newValue] = position;
this._pushToHeaps(position, newValue);
return position;
};
_proto._pushToHeaps = function _pushToHeaps(
/*number*/
position,
/*number*/
value) {
var element = {
position: position,
value: value
}; // We can reuse the same object in both heaps, because we don't mutate them
this._smallValues.push(element);
this._largeValues.push(element);
};
_proto._cleanHeaps = function _cleanHeaps() {
// We not usually only remove object from one heap while moving value.
// Here we make sure that there is no stale data on top of heaps.
this._cleanHeap(this._smallValues);
this._cleanHeap(this._largeValues);
var minHeapSize = Math.min(this._smallValues.size(), this._largeValues.size());
var maxHeapSize = Math.max(this._smallValues.size(), this._largeValues.size());
if (maxHeapSize > 10 * minHeapSize) {
// There are many old values in one of heaps. We nned to get rid of them
// to not use too avoid memory leaks
this._recreateHeaps();
}
};
_proto._recreateHeaps = function _recreateHeaps() {
var sourceHeap = this._smallValues.size() < this._largeValues.size() ? this._smallValues : this._largeValues;
var newSmallValues = new Heap([], // Initial data in the heap
this._smallerComparator);
var newLargeValues = new Heap([], // Initial datat in the heap
this._greaterComparator);
while (!sourceHeap.empty()) {
var element = sourceHeap.pop(); // Push all stil valid elements to new heaps
if (this._valueToPositionMap[element.value] !== undefined) {
newSmallValues.push(element);
newLargeValues.push(element);
}
}
this._smallValues = newSmallValues;
this._largeValues = newLargeValues;
};
_proto._cleanHeap = function _cleanHeap(
/*object*/
heap) {
while (!heap.empty() && this._valueToPositionMap[heap.peek().value] === undefined) {
heap.pop();
}
};
_proto._smallerComparator = function _smallerComparator(
/*object*/
lhs,
/*object*/
rhs)
/*boolean*/
{
return lhs.value < rhs.value;
};
_proto._greaterComparator = function _greaterComparator(
/*object*/
lhs,
/*object*/
rhs)
/*boolean*/
{
return lhs.value > rhs.value;
};
return IntegerBufferSet;
}();
module.exports = IntegerBufferSet;

View File

@@ -0,0 +1,206 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule IntegerBufferSet
* @typechecks
*/
'use strict';
const Heap = require("./Heap");
const invariant = require("./invariant"); // Data structure that allows to store values and assign positions to them
// in a way to minimize changing positions of stored values when new ones are
// added or when some values are replaced. Stored elements are alwasy assigned
// a consecutive set of positoins startin from 0 up to count of elements less 1
// Following actions can be executed
// * get position assigned to given value (null if value is not stored)
// * create new entry for new value and get assigned position back
// * replace value that is furthest from specified value range with new value
// and get it's position back
// All operations take amortized log(n) time where n is number of elements in
// the set.
class IntegerBufferSet {
constructor() {
this._valueToPositionMap = {};
this._size = 0;
this._smallValues = new Heap([], // Initial data in the heap
this._smallerComparator);
this._largeValues = new Heap([], // Initial data in the heap
this._greaterComparator);
this.getNewPositionForValue = this.getNewPositionForValue.bind(this);
this.getValuePosition = this.getValuePosition.bind(this);
this.getSize = this.getSize.bind(this);
this.replaceFurthestValuePosition = this.replaceFurthestValuePosition.bind(this);
}
getSize()
/*number*/
{
return this._size;
}
getValuePosition(
/*number*/
value)
/*?number*/
{
if (this._valueToPositionMap[value] === undefined) {
return null;
}
return this._valueToPositionMap[value];
}
getNewPositionForValue(
/*number*/
value)
/*number*/
{
invariant(this._valueToPositionMap[value] === undefined, "Shouldn't try to find new position for value already stored in BufferSet");
const newPosition = this._size;
this._size++;
this._pushToHeaps(newPosition, value);
this._valueToPositionMap[value] = newPosition;
return newPosition;
}
replaceFurthestValuePosition(
/*number*/
lowValue,
/*number*/
highValue,
/*number*/
newValue)
/*?number*/
{
invariant(this._valueToPositionMap[newValue] === undefined, "Shouldn't try to replace values with value already stored value in " + "BufferSet");
this._cleanHeaps();
if (this._smallValues.empty() || this._largeValues.empty()) {
// Threre are currently no values stored. We will have to create new
// position for this value.
return null;
}
const minValue = this._smallValues.peek().value;
const maxValue = this._largeValues.peek().value;
if (minValue >= lowValue && maxValue <= highValue) {
// All values currently stored are necessary, we can't reuse any of them.
return null;
}
let valueToReplace;
if (lowValue - minValue > maxValue - highValue) {
// minValue is further from provided range. We will reuse it's position.
valueToReplace = minValue;
this._smallValues.pop();
} else {
valueToReplace = maxValue;
this._largeValues.pop();
}
const position = this._valueToPositionMap[valueToReplace];
delete this._valueToPositionMap[valueToReplace];
this._valueToPositionMap[newValue] = position;
this._pushToHeaps(position, newValue);
return position;
}
_pushToHeaps(
/*number*/
position,
/*number*/
value) {
const element = {
position,
value
}; // We can reuse the same object in both heaps, because we don't mutate them
this._smallValues.push(element);
this._largeValues.push(element);
}
_cleanHeaps() {
// We not usually only remove object from one heap while moving value.
// Here we make sure that there is no stale data on top of heaps.
this._cleanHeap(this._smallValues);
this._cleanHeap(this._largeValues);
const minHeapSize = Math.min(this._smallValues.size(), this._largeValues.size());
const maxHeapSize = Math.max(this._smallValues.size(), this._largeValues.size());
if (maxHeapSize > 10 * minHeapSize) {
// There are many old values in one of heaps. We nned to get rid of them
// to not use too avoid memory leaks
this._recreateHeaps();
}
}
_recreateHeaps() {
const sourceHeap = this._smallValues.size() < this._largeValues.size() ? this._smallValues : this._largeValues;
const newSmallValues = new Heap([], // Initial data in the heap
this._smallerComparator);
const newLargeValues = new Heap([], // Initial datat in the heap
this._greaterComparator);
while (!sourceHeap.empty()) {
const element = sourceHeap.pop(); // Push all stil valid elements to new heaps
if (this._valueToPositionMap[element.value] !== undefined) {
newSmallValues.push(element);
newLargeValues.push(element);
}
}
this._smallValues = newSmallValues;
this._largeValues = newLargeValues;
}
_cleanHeap(
/*object*/
heap) {
while (!heap.empty() && this._valueToPositionMap[heap.peek().value] === undefined) {
heap.pop();
}
}
_smallerComparator(
/*object*/
lhs,
/*object*/
rhs)
/*boolean*/
{
return lhs.value < rhs.value;
}
_greaterComparator(
/*object*/
lhs,
/*object*/
rhs)
/*boolean*/
{
return lhs.value > rhs.value;
}
}
module.exports = IntegerBufferSet;

33
smart-app-city/frontend/node_modules/fbjs/lib/Keys.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
module.exports = {
BACKSPACE: 8,
TAB: 9,
RETURN: 13,
ALT: 18,
ESC: 27,
SPACE: 32,
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46,
COMMA: 188,
PERIOD: 190,
A: 65,
Z: 90,
ZERO: 48,
NUMPAD_0: 96,
NUMPAD_9: 105
};

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Keys
*/
module.exports = {
BACKSPACE: 8,
TAB: 9,
RETURN: 13,
ALT: 18,
ESC: 27,
SPACE: 32,
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46,
COMMA: 188,
PERIOD: 190,
A: 65,
Z: 90,
ZERO: 48,
NUMPAD_0: 96,
NUMPAD_9: 105
};

View File

@@ -0,0 +1,25 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var SiteData = require("./SiteData");
var ExecutionEnvironment = require("./ExecutionEnvironment");
function isRTL() {
if (!ExecutionEnvironment.canUseDOM) {
return false;
} else {
return SiteData.is_rtl;
}
}
var Locale = {
isRTL: isRTL
};
module.exports = Locale;

View File

@@ -0,0 +1,24 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Locale
*/
const SiteData = require("./SiteData");
const ExecutionEnvironment = require("./ExecutionEnvironment");
function isRTL() {
if (!ExecutionEnvironment.canUseDOM) {
return false;
} else {
return SiteData.is_rtl;
}
}
var Locale = {
isRTL: isRTL
};
module.exports = Locale;

View File

@@ -0,0 +1,25 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var PhotosMimeType = {
isImage: function isImage(mimeString) {
return getParts(mimeString)[0] === 'image';
},
isJpeg: function isJpeg(mimeString) {
var parts = getParts(mimeString);
return PhotosMimeType.isImage(mimeString) && ( // see http://fburl.com/10972194
parts[1] === 'jpeg' || parts[1] === 'pjpeg');
}
};
function getParts(mimeString) {
return mimeString.split('/');
}
module.exports = PhotosMimeType;

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule PhotosMimeType
*/
const PhotosMimeType = {
isImage(mimeString) {
return getParts(mimeString)[0] === 'image';
},
isJpeg(mimeString) {
const parts = getParts(mimeString);
return PhotosMimeType.isImage(mimeString) && ( // see http://fburl.com/10972194
parts[1] === 'jpeg' || parts[1] === 'pjpeg');
}
};
function getParts(mimeString) {
return mimeString.split('/');
}
module.exports = PhotosMimeType;

View File

@@ -0,0 +1,252 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @typechecks
*/
'use strict';
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var invariant = require("./invariant");
var parent = function parent(node) {
return Math.floor(node / 2);
};
var Int32Array = global.Int32Array || function (size) {
var xs = [];
for (var i = size - 1; i >= 0; --i) {
xs[i] = 0;
}
return xs;
};
/**
* Computes the next power of 2 after or equal to x.
*/
function ceilLog2(x) {
var y = 1;
while (y < x) {
y *= 2;
}
return y;
}
/**
* A prefix interval tree stores an numeric array and the partial sums of that
* array. It is optimized for updating the values of the array without
* recomputing all of the partial sums.
*
* - O(ln n) update
* - O(1) lookup
* - O(ln n) compute a partial sum
* - O(n) space
*
* Note that the sequence of partial sums is one longer than the array, so that
* the first partial sum is always 0, and the last partial sum is the sum of the
* entire array.
*/
var PrefixIntervalTree = /*#__PURE__*/function () {
/**
* Number of elements in the array
*/
/**
* Half the size of the heap. It is also the number of non-leaf nodes, and the
* index of the first element in the heap. Always a power of 2.
*/
/**
* Binary heap
*/
function PrefixIntervalTree(xs) {
_defineProperty(this, "_size", void 0);
_defineProperty(this, "_half", void 0);
_defineProperty(this, "_heap", void 0);
this._size = xs.length;
this._half = ceilLog2(this._size);
this._heap = new Int32Array(2 * this._half);
var i;
for (i = 0; i < this._size; ++i) {
this._heap[this._half + i] = xs[i];
}
for (i = this._half - 1; i > 0; --i) {
this._heap[i] = this._heap[2 * i] + this._heap[2 * i + 1];
}
}
PrefixIntervalTree.uniform = function uniform(size, initialValue) {
var xs = [];
for (var i = size - 1; i >= 0; --i) {
xs[i] = initialValue;
}
return new PrefixIntervalTree(xs);
};
PrefixIntervalTree.empty = function empty(size) {
return PrefixIntervalTree.uniform(size, 0);
};
var _proto = PrefixIntervalTree.prototype;
_proto.set = function set(index, value) {
!(0 <= index && index < this._size) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Index out of range %s', index) : invariant(false) : void 0;
var node = this._half + index;
this._heap[node] = value;
node = parent(node);
for (; node !== 0; node = parent(node)) {
this._heap[node] = this._heap[2 * node] + this._heap[2 * node + 1];
}
};
_proto.get = function get(index) {
!(0 <= index && index < this._size) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Index out of range %s', index) : invariant(false) : void 0;
var node = this._half + index;
return this._heap[node];
};
_proto.getSize = function getSize() {
return this._size;
};
/**
* Returns the sum get(0) + get(1) + ... + get(end - 1).
*/
_proto.sumUntil = function sumUntil(end) {
!(0 <= end && end < this._size + 1) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Index out of range %s', end) : invariant(false) : void 0;
if (end === 0) {
return 0;
}
var node = this._half + end - 1;
var sum = this._heap[node];
for (; node !== 1; node = parent(node)) {
if (node % 2 === 1) {
sum += this._heap[node - 1];
}
}
return sum;
};
/**
* Returns the sum get(0) + get(1) + ... + get(inclusiveEnd).
*/
_proto.sumTo = function sumTo(inclusiveEnd) {
!(0 <= inclusiveEnd && inclusiveEnd < this._size) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Index out of range %s', inclusiveEnd) : invariant(false) : void 0;
return this.sumUntil(inclusiveEnd + 1);
};
/**
* Returns the sum get(begin) + get(begin + 1) + ... + get(end - 1).
*/
_proto.sum = function sum(begin, end) {
!(begin <= end) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Begin must precede end') : invariant(false) : void 0;
return this.sumUntil(end) - this.sumUntil(begin);
};
/**
* Returns the smallest i such that 0 <= i <= size and sumUntil(i) <= t, or
* -1 if no such i exists.
*/
_proto.greatestLowerBound = function greatestLowerBound(t) {
if (t < 0) {
return -1;
}
var node = 1;
if (this._heap[node] <= t) {
return this._size;
}
while (node < this._half) {
var leftSum = this._heap[2 * node];
if (t < leftSum) {
node = 2 * node;
} else {
node = 2 * node + 1;
t -= leftSum;
}
}
return node - this._half;
};
/**
* Returns the smallest i such that 0 <= i <= size and sumUntil(i) < t, or
* -1 if no such i exists.
*/
_proto.greatestStrictLowerBound = function greatestStrictLowerBound(t) {
if (t <= 0) {
return -1;
}
var node = 1;
if (this._heap[node] < t) {
return this._size;
}
while (node < this._half) {
var leftSum = this._heap[2 * node];
if (t <= leftSum) {
node = 2 * node;
} else {
node = 2 * node + 1;
t -= leftSum;
}
}
return node - this._half;
};
/**
* Returns the smallest i such that 0 <= i <= size and t <= sumUntil(i), or
* size + 1 if no such i exists.
*/
_proto.leastUpperBound = function leastUpperBound(t) {
return this.greatestStrictLowerBound(t) + 1;
};
/**
* Returns the smallest i such that 0 <= i <= size and t < sumUntil(i), or
* size + 1 if no such i exists.
*/
_proto.leastStrictUpperBound = function leastStrictUpperBound(t) {
return this.greatestLowerBound(t) + 1;
};
return PrefixIntervalTree;
}();
module.exports = PrefixIntervalTree;

View File

@@ -0,0 +1,244 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule PrefixIntervalTree
* @flow
* @typechecks
*/
'use strict';
const invariant = require("./invariant");
const parent = node => Math.floor(node / 2);
const Int32Array = global.Int32Array || function (size: number): Array<number> {
const xs = [];
for (let i = size - 1; i >= 0; --i) {
xs[i] = 0;
}
return xs;
};
/**
* Computes the next power of 2 after or equal to x.
*/
function ceilLog2(x: number): number {
let y = 1;
while (y < x) {
y *= 2;
}
return y;
}
/**
* A prefix interval tree stores an numeric array and the partial sums of that
* array. It is optimized for updating the values of the array without
* recomputing all of the partial sums.
*
* - O(ln n) update
* - O(1) lookup
* - O(ln n) compute a partial sum
* - O(n) space
*
* Note that the sequence of partial sums is one longer than the array, so that
* the first partial sum is always 0, and the last partial sum is the sum of the
* entire array.
*/
class PrefixIntervalTree {
/**
* Number of elements in the array
*/
_size: number;
/**
* Half the size of the heap. It is also the number of non-leaf nodes, and the
* index of the first element in the heap. Always a power of 2.
*/
_half: number;
/**
* Binary heap
*/
_heap: Int32Array;
constructor(xs: Array<number>) {
this._size = xs.length;
this._half = ceilLog2(this._size);
this._heap = new Int32Array(2 * this._half);
let i;
for (i = 0; i < this._size; ++i) {
this._heap[this._half + i] = xs[i];
}
for (i = this._half - 1; i > 0; --i) {
this._heap[i] = this._heap[2 * i] + this._heap[2 * i + 1];
}
}
static uniform(size: number, initialValue: number): PrefixIntervalTree {
const xs = [];
for (let i = size - 1; i >= 0; --i) {
xs[i] = initialValue;
}
return new PrefixIntervalTree(xs);
}
static empty(size: number): PrefixIntervalTree {
return PrefixIntervalTree.uniform(size, 0);
}
set(index: number, value: number): void {
invariant(0 <= index && index < this._size, 'Index out of range %s', index);
let node = this._half + index;
this._heap[node] = value;
node = parent(node);
for (; node !== 0; node = parent(node)) {
this._heap[node] = this._heap[2 * node] + this._heap[2 * node + 1];
}
}
get(index: number): number {
invariant(0 <= index && index < this._size, 'Index out of range %s', index);
const node = this._half + index;
return this._heap[node];
}
getSize(): number {
return this._size;
}
/**
* Returns the sum get(0) + get(1) + ... + get(end - 1).
*/
sumUntil(end: number): number {
invariant(0 <= end && end < this._size + 1, 'Index out of range %s', end);
if (end === 0) {
return 0;
}
let node = this._half + end - 1;
let sum = this._heap[node];
for (; node !== 1; node = parent(node)) {
if (node % 2 === 1) {
sum += this._heap[node - 1];
}
}
return sum;
}
/**
* Returns the sum get(0) + get(1) + ... + get(inclusiveEnd).
*/
sumTo(inclusiveEnd: number): number {
invariant(0 <= inclusiveEnd && inclusiveEnd < this._size, 'Index out of range %s', inclusiveEnd);
return this.sumUntil(inclusiveEnd + 1);
}
/**
* Returns the sum get(begin) + get(begin + 1) + ... + get(end - 1).
*/
sum(begin: number, end: number): number {
invariant(begin <= end, 'Begin must precede end');
return this.sumUntil(end) - this.sumUntil(begin);
}
/**
* Returns the smallest i such that 0 <= i <= size and sumUntil(i) <= t, or
* -1 if no such i exists.
*/
greatestLowerBound(t: number): number {
if (t < 0) {
return -1;
}
let node = 1;
if (this._heap[node] <= t) {
return this._size;
}
while (node < this._half) {
const leftSum = this._heap[2 * node];
if (t < leftSum) {
node = 2 * node;
} else {
node = 2 * node + 1;
t -= leftSum;
}
}
return node - this._half;
}
/**
* Returns the smallest i such that 0 <= i <= size and sumUntil(i) < t, or
* -1 if no such i exists.
*/
greatestStrictLowerBound(t: number): number {
if (t <= 0) {
return -1;
}
let node = 1;
if (this._heap[node] < t) {
return this._size;
}
while (node < this._half) {
const leftSum = this._heap[2 * node];
if (t <= leftSum) {
node = 2 * node;
} else {
node = 2 * node + 1;
t -= leftSum;
}
}
return node - this._half;
}
/**
* Returns the smallest i such that 0 <= i <= size and t <= sumUntil(i), or
* size + 1 if no such i exists.
*/
leastUpperBound(t: number): number {
return this.greatestStrictLowerBound(t) + 1;
}
/**
* Returns the smallest i such that 0 <= i <= size and t < sumUntil(i), or
* size + 1 if no such i exists.
*/
leastStrictUpperBound(t: number): number {
return this.greatestLowerBound(t) + 1;
}
}
module.exports = PrefixIntervalTree;

View File

@@ -0,0 +1,10 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
module.exports = require("promise");

View File

@@ -0,0 +1,9 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Promise
*/
module.exports = require("promise");

View File

@@ -0,0 +1,26 @@
/**
*
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* This module wraps and augments the minimally ES6-compliant Promise
* implementation provided by the promise npm package.
*
*/
'use strict';
var Promise = require("promise/setimmediate/es6-extensions");
require("promise/setimmediate/done");
/**
* Handle either fulfillment or rejection with the same callback.
*/
Promise.prototype["finally"] = function (onSettled) {
return this.then(onSettled, onSettled);
};
module.exports = Promise;

View File

@@ -0,0 +1,26 @@
/**
*
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* This module wraps and augments the minimally ES6-compliant Promise
* implementation provided by the promise npm package.
*
*/
'use strict';
var Promise = require("promise/setimmediate/es6-extensions");
require("promise/setimmediate/done");
/**
* Handle either fulfillment or rejection with the same callback.
*/
Promise.prototype.finally = function (onSettled) {
return this.then(onSettled, onSettled);
};
module.exports = Promise;

View File

@@ -0,0 +1,59 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
'use strict';
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var Deferred = require("./Deferred");
var invariant = require("./invariant");
/**
* A map of asynchronous values that can be get or set in any order. Unlike a
* normal map, setting the value for a particular key more than once throws.
* Also unlike a normal map, a key can either be resolved or rejected.
*/
var PromiseMap = /*#__PURE__*/function () {
function PromiseMap() {
_defineProperty(this, "_deferred", void 0);
this._deferred = {};
}
var _proto = PromiseMap.prototype;
_proto.get = function get(key) {
return getDeferred(this._deferred, key).getPromise();
};
_proto.resolveKey = function resolveKey(key, value) {
var entry = getDeferred(this._deferred, key);
!!entry.isSettled() ? process.env.NODE_ENV !== "production" ? invariant(false, 'PromiseMap: Already settled `%s`.', key) : invariant(false) : void 0;
entry.resolve(value);
};
_proto.rejectKey = function rejectKey(key, reason) {
var entry = getDeferred(this._deferred, key);
!!entry.isSettled() ? process.env.NODE_ENV !== "production" ? invariant(false, 'PromiseMap: Already settled `%s`.', key) : invariant(false) : void 0;
entry.reject(reason);
};
return PromiseMap;
}();
function getDeferred(entries, key) {
if (!entries.hasOwnProperty(key)) {
entries[key] = new Deferred();
}
return entries[key];
}
module.exports = PromiseMap;

View File

@@ -0,0 +1,59 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule PromiseMap
* @flow
*/
'use strict';
const Deferred = require("./Deferred");
const invariant = require("./invariant");
/**
* A map of asynchronous values that can be get or set in any order. Unlike a
* normal map, setting the value for a particular key more than once throws.
* Also unlike a normal map, a key can either be resolved or rejected.
*/
class PromiseMap<Tvalue, Treason> {
_deferred: {
[key: string]: Deferred<any, any>
};
constructor() {
this._deferred = {};
}
get(key: string): Promise<any> {
return getDeferred(this._deferred, key).getPromise();
}
resolveKey(key: string, value: Tvalue): void {
const entry = getDeferred(this._deferred, key);
invariant(!entry.isSettled(), 'PromiseMap: Already settled `%s`.', key);
entry.resolve(value);
}
rejectKey(key: string, reason: Treason): void {
const entry = getDeferred(this._deferred, key);
invariant(!entry.isSettled(), 'PromiseMap: Already settled `%s`.', key);
entry.reject(reason);
}
}
function getDeferred(entries: {
[key: string]: Deferred<any, any>
}, key: string): Deferred<any, any> {
if (!entries.hasOwnProperty(key)) {
entries[key] = new Deferred();
}
return entries[key];
}
module.exports = PromiseMap;

View File

@@ -0,0 +1,107 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* This is utility that hanlds onWheel events and calls provided wheel
* callback with correct frame rate.
*
* @typechecks
*/
'use strict';
var emptyFunction = require("./emptyFunction");
var normalizeWheel = require("./normalizeWheel");
var requestAnimationFramePolyfill = require("./requestAnimationFramePolyfill");
var ReactWheelHandler = /*#__PURE__*/function () {
/**
* onWheel is the callback that will be called with right frame rate if
* any wheel events happened
* onWheel should is to be called with two arguments: deltaX and deltaY in
* this order
*/
function ReactWheelHandler(
/*function*/
onWheel,
/*boolean|function*/
handleScrollX,
/*boolean|function*/
handleScrollY,
/*?boolean|?function*/
stopPropagation) {
this._animationFrameID = null;
this._deltaX = 0;
this._deltaY = 0;
this._didWheel = this._didWheel.bind(this);
if (typeof handleScrollX !== 'function') {
handleScrollX = handleScrollX ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
}
if (typeof handleScrollY !== 'function') {
handleScrollY = handleScrollY ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
}
if (typeof stopPropagation !== 'function') {
stopPropagation = stopPropagation ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
}
this._handleScrollX = handleScrollX;
this._handleScrollY = handleScrollY;
this._stopPropagation = stopPropagation;
this._onWheelCallback = onWheel;
this.onWheel = this.onWheel.bind(this);
}
var _proto = ReactWheelHandler.prototype;
_proto.onWheel = function onWheel(
/*object*/
event) {
var normalizedEvent = normalizeWheel(event);
var deltaX = this._deltaX + normalizedEvent.pixelX;
var deltaY = this._deltaY + normalizedEvent.pixelY;
var handleScrollX = this._handleScrollX(deltaX, deltaY);
var handleScrollY = this._handleScrollY(deltaY, deltaX);
if (!handleScrollX && !handleScrollY) {
return;
}
this._deltaX += handleScrollX ? normalizedEvent.pixelX : 0;
this._deltaY += handleScrollY ? normalizedEvent.pixelY : 0;
event.preventDefault();
var changed;
if (this._deltaX !== 0 || this._deltaY !== 0) {
if (this._stopPropagation()) {
event.stopPropagation();
}
changed = true;
}
if (changed === true && this._animationFrameID === null) {
this._animationFrameID = requestAnimationFramePolyfill(this._didWheel);
}
};
_proto._didWheel = function _didWheel() {
this._animationFrameID = null;
this._onWheelCallback(this._deltaX, this._deltaY);
this._deltaX = 0;
this._deltaY = 0;
};
return ReactWheelHandler;
}();
module.exports = ReactWheelHandler;

View File

@@ -0,0 +1,105 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* This is utility that hanlds onWheel events and calls provided wheel
* callback with correct frame rate.
*
* @providesModule ReactWheelHandler
* @typechecks
*/
'use strict';
const emptyFunction = require("./emptyFunction");
const normalizeWheel = require("./normalizeWheel");
const requestAnimationFramePolyfill = require("./requestAnimationFramePolyfill");
class ReactWheelHandler {
/**
* onWheel is the callback that will be called with right frame rate if
* any wheel events happened
* onWheel should is to be called with two arguments: deltaX and deltaY in
* this order
*/
constructor(
/*function*/
onWheel,
/*boolean|function*/
handleScrollX,
/*boolean|function*/
handleScrollY,
/*?boolean|?function*/
stopPropagation) {
this._animationFrameID = null;
this._deltaX = 0;
this._deltaY = 0;
this._didWheel = this._didWheel.bind(this);
if (typeof handleScrollX !== 'function') {
handleScrollX = handleScrollX ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
}
if (typeof handleScrollY !== 'function') {
handleScrollY = handleScrollY ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
}
if (typeof stopPropagation !== 'function') {
stopPropagation = stopPropagation ? emptyFunction.thatReturnsTrue : emptyFunction.thatReturnsFalse;
}
this._handleScrollX = handleScrollX;
this._handleScrollY = handleScrollY;
this._stopPropagation = stopPropagation;
this._onWheelCallback = onWheel;
this.onWheel = this.onWheel.bind(this);
}
onWheel(
/*object*/
event) {
const normalizedEvent = normalizeWheel(event);
const deltaX = this._deltaX + normalizedEvent.pixelX;
const deltaY = this._deltaY + normalizedEvent.pixelY;
const handleScrollX = this._handleScrollX(deltaX, deltaY);
const handleScrollY = this._handleScrollY(deltaY, deltaX);
if (!handleScrollX && !handleScrollY) {
return;
}
this._deltaX += handleScrollX ? normalizedEvent.pixelX : 0;
this._deltaY += handleScrollY ? normalizedEvent.pixelY : 0;
event.preventDefault();
let changed;
if (this._deltaX !== 0 || this._deltaY !== 0) {
if (this._stopPropagation()) {
event.stopPropagation();
}
changed = true;
}
if (changed === true && this._animationFrameID === null) {
this._animationFrameID = requestAnimationFramePolyfill(this._didWheel);
}
}
_didWheel() {
this._animationFrameID = null;
this._onWheelCallback(this._deltaX, this._deltaY);
this._deltaX = 0;
this._deltaY = 0;
}
}
module.exports = ReactWheelHandler;

View File

@@ -0,0 +1,83 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* @param {DOMElement} element
* @param {DOMDocument} doc
* @return {boolean}
*/
function _isViewportScrollElement(element, doc) {
return !!doc && (element === doc.documentElement || element === doc.body);
}
/**
* Scroll Module. This class contains 4 simple static functions
* to be used to access Element.scrollTop/scrollLeft properties.
* To solve the inconsistencies between browsers when either
* document.body or document.documentElement is supplied,
* below logic will be used to alleviate the issue:
*
* 1. If 'element' is either 'document.body' or 'document.documentElement,
* get whichever element's 'scroll{Top,Left}' is larger.
* 2. If 'element' is either 'document.body' or 'document.documentElement',
* set the 'scroll{Top,Left}' on both elements.
*/
var Scroll = {
/**
* @param {DOMElement} element
* @return {number}
*/
getTop: function getTop(element) {
var doc = element.ownerDocument;
return _isViewportScrollElement(element, doc) ? // In practice, they will either both have the same value,
// or one will be zero and the other will be the scroll position
// of the viewport. So we can use `X || Y` instead of `Math.max(X, Y)`
doc.body.scrollTop || doc.documentElement.scrollTop : element.scrollTop;
},
/**
* @param {DOMElement} element
* @param {number} newTop
*/
setTop: function setTop(element, newTop) {
var doc = element.ownerDocument;
if (_isViewportScrollElement(element, doc)) {
doc.body.scrollTop = doc.documentElement.scrollTop = newTop;
} else {
element.scrollTop = newTop;
}
},
/**
* @param {DOMElement} element
* @return {number}
*/
getLeft: function getLeft(element) {
var doc = element.ownerDocument;
return _isViewportScrollElement(element, doc) ? doc.body.scrollLeft || doc.documentElement.scrollLeft : element.scrollLeft;
},
/**
* @param {DOMElement} element
* @param {number} newLeft
*/
setLeft: function setLeft(element, newLeft) {
var doc = element.ownerDocument;
if (_isViewportScrollElement(element, doc)) {
doc.body.scrollLeft = doc.documentElement.scrollLeft = newLeft;
} else {
element.scrollLeft = newLeft;
}
}
};
module.exports = Scroll;

View File

@@ -0,0 +1,82 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Scroll
*/
/**
* @param {DOMElement} element
* @param {DOMDocument} doc
* @return {boolean}
*/
function _isViewportScrollElement(element, doc) {
return !!doc && (element === doc.documentElement || element === doc.body);
}
/**
* Scroll Module. This class contains 4 simple static functions
* to be used to access Element.scrollTop/scrollLeft properties.
* To solve the inconsistencies between browsers when either
* document.body or document.documentElement is supplied,
* below logic will be used to alleviate the issue:
*
* 1. If 'element' is either 'document.body' or 'document.documentElement,
* get whichever element's 'scroll{Top,Left}' is larger.
* 2. If 'element' is either 'document.body' or 'document.documentElement',
* set the 'scroll{Top,Left}' on both elements.
*/
const Scroll = {
/**
* @param {DOMElement} element
* @return {number}
*/
getTop: function (element) {
const doc = element.ownerDocument;
return _isViewportScrollElement(element, doc) ? // In practice, they will either both have the same value,
// or one will be zero and the other will be the scroll position
// of the viewport. So we can use `X || Y` instead of `Math.max(X, Y)`
doc.body.scrollTop || doc.documentElement.scrollTop : element.scrollTop;
},
/**
* @param {DOMElement} element
* @param {number} newTop
*/
setTop: function (element, newTop) {
const doc = element.ownerDocument;
if (_isViewportScrollElement(element, doc)) {
doc.body.scrollTop = doc.documentElement.scrollTop = newTop;
} else {
element.scrollTop = newTop;
}
},
/**
* @param {DOMElement} element
* @return {number}
*/
getLeft: function (element) {
const doc = element.ownerDocument;
return _isViewportScrollElement(element, doc) ? doc.body.scrollLeft || doc.documentElement.scrollLeft : element.scrollLeft;
},
/**
* @param {DOMElement} element
* @param {number} newLeft
*/
setLeft: function (element, newLeft) {
const doc = element.ownerDocument;
if (_isViewportScrollElement(element, doc)) {
doc.body.scrollLeft = doc.documentElement.scrollLeft = newLeft;
} else {
element.scrollLeft = newLeft;
}
}
};
module.exports = Scroll;

View File

@@ -0,0 +1,12 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
module.exports = {
is_rtl: false
};

View File

@@ -0,0 +1,11 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule SiteData
*/
module.exports = {
is_rtl: false
};

65
smart-app-city/frontend/node_modules/fbjs/lib/Style.js generated vendored Normal file
View File

@@ -0,0 +1,65 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var getStyleProperty = require("./getStyleProperty");
/**
* @param {DOMNode} element [description]
* @param {string} name Overflow style property name.
* @return {boolean} True if the supplied ndoe is scrollable.
*/
function _isNodeScrollable(element, name) {
var overflow = Style.get(element, name);
return overflow === 'auto' || overflow === 'scroll';
}
/**
* Utilities for querying and mutating style properties.
*/
var Style = {
/**
* Gets the style property for the supplied node. This will return either the
* computed style, if available, or the declared style.
*
* @param {DOMNode} node
* @param {string} name Style property name.
* @return {?string} Style property value.
*/
get: getStyleProperty,
/**
* Determines the nearest ancestor of a node that is scrollable.
*
* NOTE: This can be expensive if used repeatedly or on a node nested deeply.
*
* @param {?DOMNode} node Node from which to start searching.
* @return {?DOMWindow|DOMElement} Scroll parent of the supplied node.
*/
getScrollParent: function getScrollParent(node) {
if (!node) {
return null;
}
var ownerDocument = node.ownerDocument;
while (node && node !== ownerDocument.body) {
if (_isNodeScrollable(node, 'overflow') || _isNodeScrollable(node, 'overflowY') || _isNodeScrollable(node, 'overflowX')) {
return node;
}
node = node.parentNode;
}
return ownerDocument.defaultView || ownerDocument.parentWindow;
}
};
module.exports = Style;

View File

@@ -0,0 +1,64 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Style
* @typechecks
*/
var getStyleProperty = require("./getStyleProperty");
/**
* @param {DOMNode} element [description]
* @param {string} name Overflow style property name.
* @return {boolean} True if the supplied ndoe is scrollable.
*/
function _isNodeScrollable(element, name) {
var overflow = Style.get(element, name);
return overflow === 'auto' || overflow === 'scroll';
}
/**
* Utilities for querying and mutating style properties.
*/
var Style = {
/**
* Gets the style property for the supplied node. This will return either the
* computed style, if available, or the declared style.
*
* @param {DOMNode} node
* @param {string} name Style property name.
* @return {?string} Style property value.
*/
get: getStyleProperty,
/**
* Determines the nearest ancestor of a node that is scrollable.
*
* NOTE: This can be expensive if used repeatedly or on a node nested deeply.
*
* @param {?DOMNode} node Node from which to start searching.
* @return {?DOMWindow|DOMElement} Scroll parent of the supplied node.
*/
getScrollParent: function (node) {
if (!node) {
return null;
}
var ownerDocument = node.ownerDocument;
while (node && node !== ownerDocument.body) {
if (_isNodeScrollable(node, 'overflow') || _isNodeScrollable(node, 'overflowY') || _isNodeScrollable(node, 'overflowX')) {
return node;
}
node = node.parentNode;
}
return ownerDocument.defaultView || ownerDocument.parentWindow;
}
};
module.exports = Style;

View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
* @stub
*
*/
'use strict'; // \u00a1-\u00b1\u00b4-\u00b8\u00ba\u00bb\u00bf
// is latin supplement punctuation except fractions and superscript
// numbers
// \u2010-\u2027\u2030-\u205e
// is punctuation from the general punctuation block:
// weird quotes, commas, bullets, dashes, etc.
// \u30fb\u3001\u3002\u3008-\u3011\u3014-\u301f
// is CJK punctuation
// \uff1a-\uff1f\uff01-\uff0f\uff3b-\uff40\uff5b-\uff65
// is some full-width/half-width punctuation
// \u2E2E\u061f\u066a-\u066c\u061b\u060c\u060d\uFD3e\uFD3F
// is some Arabic punctuation marks
// \u1801\u0964\u104a\u104b
// is misc. other language punctuation marks
var PUNCTUATION = '[.,+*?$|#{}()\'\\^\\-\\[\\]\\\\\\/!@%"~=<>_:;' + "\u30FB\u3001\u3002\u3008-\u3011\u3014-\u301F\uFF1A-\uFF1F\uFF01-\uFF0F" + "\uFF3B-\uFF40\uFF5B-\uFF65\u2E2E\u061F\u066A-\u066C\u061B\u060C\u060D" + "\uFD3E\uFD3F\u1801\u0964\u104A\u104B\u2010-\u2027\u2030-\u205E" + "\xA1-\xB1\xB4-\xB8\xBA\xBB\xBF]";
module.exports = {
getPunctuation: function getPunctuation() {
return PUNCTUATION;
}
};

View File

@@ -0,0 +1,30 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule TokenizeUtil
* @typechecks
* @stub
* @flow
*/
'use strict'; // \u00a1-\u00b1\u00b4-\u00b8\u00ba\u00bb\u00bf
// is latin supplement punctuation except fractions and superscript
// numbers
// \u2010-\u2027\u2030-\u205e
// is punctuation from the general punctuation block:
// weird quotes, commas, bullets, dashes, etc.
// \u30fb\u3001\u3002\u3008-\u3011\u3014-\u301f
// is CJK punctuation
// \uff1a-\uff1f\uff01-\uff0f\uff3b-\uff40\uff5b-\uff65
// is some full-width/half-width punctuation
// \u2E2E\u061f\u066a-\u066c\u061b\u060c\u060d\uFD3e\uFD3F
// is some Arabic punctuation marks
// \u1801\u0964\u104a\u104b
// is misc. other language punctuation marks
var PUNCTUATION = '[.,+*?$|#{}()\'\\^\\-\\[\\]\\\\\\/!@%"~=<>_:;' + '\u30fb\u3001\u3002\u3008-\u3011\u3014-\u301f\uff1a-\uff1f\uff01-\uff0f' + '\uff3b-\uff40\uff5b-\uff65\u2E2E\u061f\u066a-\u066c\u061b\u060c\u060d' + '\uFD3e\uFD3F\u1801\u0964\u104a\u104b\u2010-\u2027\u2030-\u205e' + '\u00a1-\u00b1\u00b4-\u00b8\u00ba\u00bb\u00bf]';
module.exports = {
getPunctuation: (): string => PUNCTUATION
};

View File

@@ -0,0 +1,29 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
var TouchEventUtils = {
/**
* Utility function for common case of extracting out the primary touch from a
* touch event.
* - `touchEnd` events usually do not have the `touches` property.
* http://stackoverflow.com/questions/3666929/
* mobile-sarai-touchend-event-not-firing-when-last-touch-is-removed
*
* @param {Event} nativeEvent Native event that may or may not be a touch.
* @return {TouchesObject?} an object with pageX and pageY or null.
*/
extractSingleTouch: function extractSingleTouch(nativeEvent) {
var touches = nativeEvent.touches;
var changedTouches = nativeEvent.changedTouches;
var hasTouches = touches && touches.length > 0;
var hasChangedTouches = changedTouches && changedTouches.length > 0;
return !hasTouches && hasChangedTouches ? changedTouches[0] : hasTouches ? touches[0] : nativeEvent;
}
};
module.exports = TouchEventUtils;

View File

@@ -0,0 +1,28 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule TouchEventUtils
*/
const TouchEventUtils = {
/**
* Utility function for common case of extracting out the primary touch from a
* touch event.
* - `touchEnd` events usually do not have the `touches` property.
* http://stackoverflow.com/questions/3666929/
* mobile-sarai-touchend-event-not-firing-when-last-touch-is-removed
*
* @param {Event} nativeEvent Native event that may or may not be a touch.
* @return {TouchesObject?} an object with pageX and pageY or null.
*/
extractSingleTouch: function (nativeEvent) {
const touches = nativeEvent.touches;
const changedTouches = nativeEvent.changedTouches;
const hasTouches = touches && touches.length > 0;
const hasChangedTouches = changedTouches && changedTouches.length > 0;
return !hasTouches && hasChangedTouches ? changedTouches[0] : hasTouches ? touches[0] : nativeEvent;
}
};
module.exports = TouchEventUtils;

29
smart-app-city/frontend/node_modules/fbjs/lib/URI.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
'use strict';
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var URI = /*#__PURE__*/function () {
function URI(uri) {
_defineProperty(this, "_uri", void 0);
this._uri = uri;
}
var _proto = URI.prototype;
_proto.toString = function toString() {
return this._uri;
};
return URI;
}();
module.exports = URI;

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule URI
* @flow
*/
'use strict';
class URI {
_uri: string;
constructor(uri: string) {
this._uri = uri;
}
toString(): string {
return this._uri;
}
}
module.exports = URI;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,110 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*
*/
/**
* Constants to represent text directionality
*
* Also defines a *global* direciton, to be used in bidi algorithms as a
* default fallback direciton, when no better direction is found or provided.
*
* NOTE: Use `setGlobalDir()`, or update `initGlobalDir()`, to set the initial
* global direction value based on the application.
*
* Part of the implementation of Unicode Bidirectional Algorithm (UBA)
* Unicode Standard Annex #9 (UAX9)
* http://www.unicode.org/reports/tr9/
*/
'use strict';
var invariant = require("./invariant");
var NEUTRAL = 'NEUTRAL'; // No strong direction
var LTR = 'LTR'; // Left-to-Right direction
var RTL = 'RTL'; // Right-to-Left direction
var globalDir = null; // == Helpers ==
/**
* Check if a directionality value is a Strong one
*/
function isStrong(dir) {
return dir === LTR || dir === RTL;
}
/**
* Get string value to be used for `dir` HTML attribute or `direction` CSS
* property.
*/
function getHTMLDir(dir) {
!isStrong(dir) ? process.env.NODE_ENV !== "production" ? invariant(false, '`dir` must be a strong direction to be converted to HTML Direction') : invariant(false) : void 0;
return dir === LTR ? 'ltr' : 'rtl';
}
/**
* Get string value to be used for `dir` HTML attribute or `direction` CSS
* property, but returns null if `dir` has same value as `otherDir`.
* `null`.
*/
function getHTMLDirIfDifferent(dir, otherDir) {
!isStrong(dir) ? process.env.NODE_ENV !== "production" ? invariant(false, '`dir` must be a strong direction to be converted to HTML Direction') : invariant(false) : void 0;
!isStrong(otherDir) ? process.env.NODE_ENV !== "production" ? invariant(false, '`otherDir` must be a strong direction to be converted to HTML Direction') : invariant(false) : void 0;
return dir === otherDir ? null : getHTMLDir(dir);
} // == Global Direction ==
/**
* Set the global direction.
*/
function setGlobalDir(dir) {
globalDir = dir;
}
/**
* Initialize the global direction
*/
function initGlobalDir() {
setGlobalDir(LTR);
}
/**
* Get the global direction
*/
function getGlobalDir() {
if (!globalDir) {
this.initGlobalDir();
}
!globalDir ? process.env.NODE_ENV !== "production" ? invariant(false, 'Global direction not set.') : invariant(false) : void 0;
return globalDir;
}
var UnicodeBidiDirection = {
// Values
NEUTRAL: NEUTRAL,
LTR: LTR,
RTL: RTL,
// Helpers
isStrong: isStrong,
getHTMLDir: getHTMLDir,
getHTMLDirIfDifferent: getHTMLDirIfDifferent,
// Global Direction
setGlobalDir: setGlobalDir,
initGlobalDir: initGlobalDir,
getGlobalDir: getGlobalDir
};
module.exports = UnicodeBidiDirection;

View File

@@ -0,0 +1,113 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UnicodeBidiDirection
* @typechecks
* @flow
*/
/**
* Constants to represent text directionality
*
* Also defines a *global* direciton, to be used in bidi algorithms as a
* default fallback direciton, when no better direction is found or provided.
*
* NOTE: Use `setGlobalDir()`, or update `initGlobalDir()`, to set the initial
* global direction value based on the application.
*
* Part of the implementation of Unicode Bidirectional Algorithm (UBA)
* Unicode Standard Annex #9 (UAX9)
* http://www.unicode.org/reports/tr9/
*/
'use strict';
const invariant = require("./invariant");
export type BidiDirection = 'LTR' | 'RTL' | 'NEUTRAL';
export type HTMLDir = 'ltr' | 'rtl';
const NEUTRAL = 'NEUTRAL'; // No strong direction
const LTR = 'LTR'; // Left-to-Right direction
const RTL = 'RTL'; // Right-to-Left direction
let globalDir: ?BidiDirection = null; // == Helpers ==
/**
* Check if a directionality value is a Strong one
*/
function isStrong(dir: BidiDirection): boolean {
return dir === LTR || dir === RTL;
}
/**
* Get string value to be used for `dir` HTML attribute or `direction` CSS
* property.
*/
function getHTMLDir(dir: BidiDirection): HTMLDir {
invariant(isStrong(dir), '`dir` must be a strong direction to be converted to HTML Direction');
return dir === LTR ? 'ltr' : 'rtl';
}
/**
* Get string value to be used for `dir` HTML attribute or `direction` CSS
* property, but returns null if `dir` has same value as `otherDir`.
* `null`.
*/
function getHTMLDirIfDifferent(dir: BidiDirection, otherDir: BidiDirection): ?HTMLDir {
invariant(isStrong(dir), '`dir` must be a strong direction to be converted to HTML Direction');
invariant(isStrong(otherDir), '`otherDir` must be a strong direction to be converted to HTML Direction');
return dir === otherDir ? null : getHTMLDir(dir);
} // == Global Direction ==
/**
* Set the global direction.
*/
function setGlobalDir(dir: BidiDirection): void {
globalDir = dir;
}
/**
* Initialize the global direction
*/
function initGlobalDir(): void {
setGlobalDir(LTR);
}
/**
* Get the global direction
*/
function getGlobalDir(): BidiDirection {
if (!globalDir) {
this.initGlobalDir();
}
invariant(globalDir, 'Global direction not set.');
return globalDir;
}
const UnicodeBidiDirection = {
// Values
NEUTRAL,
LTR,
RTL,
// Helpers
isStrong,
getHTMLDir,
getHTMLDirIfDifferent,
// Global Direction
setGlobalDir,
initGlobalDir,
getGlobalDir
};
module.exports = UnicodeBidiDirection;

View File

@@ -0,0 +1,100 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*
*/
/**
* Stateful API for text direction detection
*
* This class can be used in applications where you need to detect the
* direction of a sequence of text blocks, where each direction shall be used
* as the fallback direction for the next one.
*
* NOTE: A default direction, if not provided, is set based on the global
* direction, as defined by `UnicodeBidiDirection`.
*
* == Example ==
* ```
* var UnicodeBidiService = require('UnicodeBidiService');
*
* var bidiService = new UnicodeBidiService();
*
* ...
*
* bidiService.reset();
* for (var para in paragraphs) {
* var dir = bidiService.getDirection(para);
* ...
* }
* ```
*
* Part of our implementation of Unicode Bidirectional Algorithm (UBA)
* Unicode Standard Annex #9 (UAX9)
* http://www.unicode.org/reports/tr9/
*/
'use strict';
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var UnicodeBidi = require("./UnicodeBidi");
var UnicodeBidiDirection = require("./UnicodeBidiDirection");
var invariant = require("./invariant");
var UnicodeBidiService = /*#__PURE__*/function () {
/**
* Stateful class for paragraph direction detection
*
* @param defaultDir Default direction of the service
*/
function UnicodeBidiService(defaultDir) {
_defineProperty(this, "_defaultDir", void 0);
_defineProperty(this, "_lastDir", void 0);
if (!defaultDir) {
defaultDir = UnicodeBidiDirection.getGlobalDir();
} else {
!UnicodeBidiDirection.isStrong(defaultDir) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Default direction must be a strong direction (LTR or RTL)') : invariant(false) : void 0;
}
this._defaultDir = defaultDir;
this.reset();
}
/**
* Reset the internal state
*
* Instead of creating a new instance, you can just reset() your instance
* everytime you start a new loop.
*/
var _proto = UnicodeBidiService.prototype;
_proto.reset = function reset() {
this._lastDir = this._defaultDir;
};
/**
* Returns the direction of a block of text, and remembers it as the
* fall-back direction for the next paragraph.
*
* @param str A text block, e.g. paragraph, table cell, tag
* @return The resolved direction
*/
_proto.getDirection = function getDirection(str) {
this._lastDir = UnicodeBidi.getDirection(str, this._lastDir);
return this._lastDir;
};
return UnicodeBidiService;
}();
module.exports = UnicodeBidiService;

View File

@@ -0,0 +1,97 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UnicodeBidiService
* @typechecks
* @flow
*/
/**
* Stateful API for text direction detection
*
* This class can be used in applications where you need to detect the
* direction of a sequence of text blocks, where each direction shall be used
* as the fallback direction for the next one.
*
* NOTE: A default direction, if not provided, is set based on the global
* direction, as defined by `UnicodeBidiDirection`.
*
* == Example ==
* ```
* var UnicodeBidiService = require('UnicodeBidiService');
*
* var bidiService = new UnicodeBidiService();
*
* ...
*
* bidiService.reset();
* for (var para in paragraphs) {
* var dir = bidiService.getDirection(para);
* ...
* }
* ```
*
* Part of our implementation of Unicode Bidirectional Algorithm (UBA)
* Unicode Standard Annex #9 (UAX9)
* http://www.unicode.org/reports/tr9/
*/
'use strict';
const UnicodeBidi = require("./UnicodeBidi");
const UnicodeBidiDirection = require("./UnicodeBidiDirection");
const invariant = require("./invariant");
import type { BidiDirection } from "./UnicodeBidiDirection";
class UnicodeBidiService {
_defaultDir: BidiDirection;
_lastDir: BidiDirection;
/**
* Stateful class for paragraph direction detection
*
* @param defaultDir Default direction of the service
*/
constructor(defaultDir: ?BidiDirection) {
if (!defaultDir) {
defaultDir = UnicodeBidiDirection.getGlobalDir();
} else {
invariant(UnicodeBidiDirection.isStrong(defaultDir), 'Default direction must be a strong direction (LTR or RTL)');
}
this._defaultDir = defaultDir;
this.reset();
}
/**
* Reset the internal state
*
* Instead of creating a new instance, you can just reset() your instance
* everytime you start a new loop.
*/
reset(): void {
this._lastDir = this._defaultDir;
}
/**
* Returns the direction of a block of text, and remembers it as the
* fall-back direction for the next paragraph.
*
* @param str A text block, e.g. paragraph, table cell, tag
* @return The resolved direction
*/
getDirection(str: string): BidiDirection {
this._lastDir = UnicodeBidi.getDirection(str, this._lastDir);
return this._lastDir;
}
}
module.exports = UnicodeBidiService;

View File

@@ -0,0 +1,175 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/**
* Unicode algorithms for CJK (Chinese, Japanese, Korean) writing systems.
*
* Utilities for Hanzi/Kanji/Hanja logographs and Kanas (Katakana and Hiragana)
* syllables.
*
* For Korean Hangul see module `UnicodeHangulKorean`.
*/
'use strict';
/**
* Latin
*
* NOTE: The code assumes these sets include only BMP characters.
*/
var R_LATIN_ASCII = 'a-zA-Z';
var R_LATIN_FULLWIDTH = "\uFF21-\uFF3A\uFF41-\uFF5A";
var R_LATIN = R_LATIN_ASCII + R_LATIN_FULLWIDTH;
/**
* Hiragana & Katakana
*
* NOTE: Some ranges include non-BMP characters. We do not support those ranges
* for now.
*/
var R_HIRAGANA = "\u3040-\u309F";
var R_KATAKANA = "\u30A0-\u30FF";
var R_KATAKANA_PHONETIC = "\u31F0-\u31FF";
var R_KATAKANA_HALFWIDTH = "\uFF65-\uFF9F"; // var R_KANA_SUPPLEMENT = '\U0001B000-\U0001B0FF';
var R_KATAKANA_ALL = R_KATAKANA + R_KATAKANA_PHONETIC + R_KATAKANA_HALFWIDTH;
var R_KANA = R_HIRAGANA + R_KATAKANA_ALL;
var I_HIRAGANA = [0x3040, 0x309F];
var I_KATAKANA = [0x30A0, 0x30FF];
var I_HIRAGANA_TO_KATAKANA = I_KATAKANA[0] - I_HIRAGANA[0];
/**
* Hanzi/Kanji/Hanja
*
* NOTE: Some ranges include non-BMP characters. We do not support those ranges
* for now.
*/
var R_IDEO_MAIN = "\u4E00-\u9FCF";
var R_IDEO_EXT_A = "\u3400-\u4DBF"; // var R_IDEO_EXT_B = '\U00020000-\U0002A6DF';
// var R_IDEO_EXT_C = '\U0002A700-\U0002B73F';
// var R_IDEO_EXT_D = '\U0002B740-\U0002B81F';
var R_IDEO = R_IDEO_MAIN + R_IDEO_EXT_A;
/**
* Hangul
*/
// var R_HANGUL_JAMO = '\u1100-\u11FF';
// var R_HANGUL_JAMO_EXT_A = '\uA960-\uA97F';
// var R_HANGUL_JAMO_EXT_B = '\uD7B0-\uD7FF';
// var R_HANGUL_COMPATIBILITY = '\u3130-\u318F';
// var R_HANGUL_COMP_HALFWIDTH = '\uFFA0-\uFFDF';
var R_HANGUL_SYLLABLES = "\uAC00-\uD7AF";
/**
* Globals
*/
var R_IDEO_OR_SYLL = R_IDEO + R_KANA + R_HANGUL_SYLLABLES;
var REGEX_IDEO = null;
var REGEX_KANA = null;
var REGEX_IDEO_OR_SYLL = null;
var REGEX_IS_KANA_WITH_TRAILING_LATIN = null;
/**
* Whether the string includes any Katakana or Hiragana characters.
*
* @param {string} str
* @return {boolean}
*/
function hasKana(str) {
REGEX_KANA = REGEX_KANA || new RegExp('[' + R_KANA + ']');
return REGEX_KANA.test(str);
}
/**
* Whether the string includes any CJK Ideograph characters.
*
* @param {string} str
* @return {boolean}
*/
function hasIdeograph(str) {
REGEX_IDEO = REGEX_IDEO || new RegExp('[' + R_IDEO + ']');
return REGEX_IDEO.test(str);
}
/**
* Whether the string includes any CJK Ideograph or Syllable characters.
*
* @param {string} str
* @return {boolean}
*/
function hasIdeoOrSyll(str) {
REGEX_IDEO_OR_SYLL = REGEX_IDEO_OR_SYLL || new RegExp('[' + R_IDEO_OR_SYLL + ']');
return REGEX_IDEO_OR_SYLL.test(str);
}
/**
* @param {string} chr
* @output {string}
*/
function charCodeToKatakana(chr) {
var charCode = chr.charCodeAt(0);
return String.fromCharCode(charCode < I_HIRAGANA[0] || charCode > I_HIRAGANA[1] ? charCode : charCode + I_HIRAGANA_TO_KATAKANA);
}
/**
* Replace any Hiragana character with the matching Katakana
*
* @param {string} str
* @output {string}
*/
function hiraganaToKatakana(str) {
if (!hasKana(str)) {
return str;
}
return str.split('').map(charCodeToKatakana).join('');
}
/**
* Whether the string is exactly a sequence of Kana characters followed by one
* Latin character.
*
* @param {string} str
* @output {string}
*/
function isKanaWithTrailingLatin(str) {
REGEX_IS_KANA_WITH_TRAILING_LATIN = REGEX_IS_KANA_WITH_TRAILING_LATIN || new RegExp('^' + '[' + R_KANA + ']+' + '[' + R_LATIN + ']' + '$');
return REGEX_IS_KANA_WITH_TRAILING_LATIN.test(str);
}
/**
* Drops the trailing Latin character from a string that is exactly a sequence
* of Kana characters followed by one Latin character.
*
* @param {string} str
* @output {string}
*/
function kanaRemoveTrailingLatin(str) {
if (isKanaWithTrailingLatin(str)) {
return str.substr(0, str.length - 1);
}
return str;
}
var UnicodeCJK = {
hasKana: hasKana,
hasIdeograph: hasIdeograph,
hasIdeoOrSyll: hasIdeoOrSyll,
hiraganaToKatakana: hiraganaToKatakana,
isKanaWithTrailingLatin: isKanaWithTrailingLatin,
kanaRemoveTrailingLatin: kanaRemoveTrailingLatin
};
module.exports = UnicodeCJK;

View File

@@ -0,0 +1,176 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UnicodeCJK
* @typechecks
*/
/**
* Unicode algorithms for CJK (Chinese, Japanese, Korean) writing systems.
*
* Utilities for Hanzi/Kanji/Hanja logographs and Kanas (Katakana and Hiragana)
* syllables.
*
* For Korean Hangul see module `UnicodeHangulKorean`.
*/
'use strict';
/**
* Latin
*
* NOTE: The code assumes these sets include only BMP characters.
*/
const R_LATIN_ASCII = 'a-zA-Z';
const R_LATIN_FULLWIDTH = '\uFF21-\uFF3A\uFF41-\uFF5A';
const R_LATIN = R_LATIN_ASCII + R_LATIN_FULLWIDTH;
/**
* Hiragana & Katakana
*
* NOTE: Some ranges include non-BMP characters. We do not support those ranges
* for now.
*/
const R_HIRAGANA = '\u3040-\u309F';
const R_KATAKANA = '\u30A0-\u30FF';
const R_KATAKANA_PHONETIC = '\u31F0-\u31FF';
const R_KATAKANA_HALFWIDTH = '\uFF65-\uFF9F'; // var R_KANA_SUPPLEMENT = '\U0001B000-\U0001B0FF';
const R_KATAKANA_ALL = R_KATAKANA + R_KATAKANA_PHONETIC + R_KATAKANA_HALFWIDTH;
const R_KANA = R_HIRAGANA + R_KATAKANA_ALL;
const I_HIRAGANA = [0x3040, 0x309F];
const I_KATAKANA = [0x30A0, 0x30FF];
const I_HIRAGANA_TO_KATAKANA = I_KATAKANA[0] - I_HIRAGANA[0];
/**
* Hanzi/Kanji/Hanja
*
* NOTE: Some ranges include non-BMP characters. We do not support those ranges
* for now.
*/
const R_IDEO_MAIN = '\u4E00-\u9FCF';
const R_IDEO_EXT_A = '\u3400-\u4DBF'; // var R_IDEO_EXT_B = '\U00020000-\U0002A6DF';
// var R_IDEO_EXT_C = '\U0002A700-\U0002B73F';
// var R_IDEO_EXT_D = '\U0002B740-\U0002B81F';
const R_IDEO = R_IDEO_MAIN + R_IDEO_EXT_A;
/**
* Hangul
*/
// var R_HANGUL_JAMO = '\u1100-\u11FF';
// var R_HANGUL_JAMO_EXT_A = '\uA960-\uA97F';
// var R_HANGUL_JAMO_EXT_B = '\uD7B0-\uD7FF';
// var R_HANGUL_COMPATIBILITY = '\u3130-\u318F';
// var R_HANGUL_COMP_HALFWIDTH = '\uFFA0-\uFFDF';
const R_HANGUL_SYLLABLES = '\uAC00-\uD7AF';
/**
* Globals
*/
const R_IDEO_OR_SYLL = R_IDEO + R_KANA + R_HANGUL_SYLLABLES;
let REGEX_IDEO = null;
let REGEX_KANA = null;
let REGEX_IDEO_OR_SYLL = null;
let REGEX_IS_KANA_WITH_TRAILING_LATIN = null;
/**
* Whether the string includes any Katakana or Hiragana characters.
*
* @param {string} str
* @return {boolean}
*/
function hasKana(str) {
REGEX_KANA = REGEX_KANA || new RegExp('[' + R_KANA + ']');
return REGEX_KANA.test(str);
}
/**
* Whether the string includes any CJK Ideograph characters.
*
* @param {string} str
* @return {boolean}
*/
function hasIdeograph(str) {
REGEX_IDEO = REGEX_IDEO || new RegExp('[' + R_IDEO + ']');
return REGEX_IDEO.test(str);
}
/**
* Whether the string includes any CJK Ideograph or Syllable characters.
*
* @param {string} str
* @return {boolean}
*/
function hasIdeoOrSyll(str) {
REGEX_IDEO_OR_SYLL = REGEX_IDEO_OR_SYLL || new RegExp('[' + R_IDEO_OR_SYLL + ']');
return REGEX_IDEO_OR_SYLL.test(str);
}
/**
* @param {string} chr
* @output {string}
*/
function charCodeToKatakana(chr) {
const charCode = chr.charCodeAt(0);
return String.fromCharCode(charCode < I_HIRAGANA[0] || charCode > I_HIRAGANA[1] ? charCode : charCode + I_HIRAGANA_TO_KATAKANA);
}
/**
* Replace any Hiragana character with the matching Katakana
*
* @param {string} str
* @output {string}
*/
function hiraganaToKatakana(str) {
if (!hasKana(str)) {
return str;
}
return str.split('').map(charCodeToKatakana).join('');
}
/**
* Whether the string is exactly a sequence of Kana characters followed by one
* Latin character.
*
* @param {string} str
* @output {string}
*/
function isKanaWithTrailingLatin(str) {
REGEX_IS_KANA_WITH_TRAILING_LATIN = REGEX_IS_KANA_WITH_TRAILING_LATIN || new RegExp('^' + '[' + R_KANA + ']+' + '[' + R_LATIN + ']' + '$');
return REGEX_IS_KANA_WITH_TRAILING_LATIN.test(str);
}
/**
* Drops the trailing Latin character from a string that is exactly a sequence
* of Kana characters followed by one Latin character.
*
* @param {string} str
* @output {string}
*/
function kanaRemoveTrailingLatin(str) {
if (isKanaWithTrailingLatin(str)) {
return str.substr(0, str.length - 1);
}
return str;
}
const UnicodeCJK = {
hasKana: hasKana,
hasIdeograph: hasIdeograph,
hasIdeoOrSyll: hasIdeoOrSyll,
hiraganaToKatakana: hiraganaToKatakana,
isKanaWithTrailingLatin: isKanaWithTrailingLatin,
kanaRemoveTrailingLatin: kanaRemoveTrailingLatin
};
module.exports = UnicodeCJK;

View File

@@ -0,0 +1,136 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/**
* Unicode algorithms for Hangul script, the Korean writing system
*
* Hangul script has three encoded models in Unicode:
*
* A) Conjoining Jamo (covers modern and historic elements)
* * U+1100..U+11FF ; Hangul Jamo
* * U+A960..U+A97F ; Hangul Jamo Extended-A
* * U+D7B0..U+D7FF ; Hangul Jamo Extended-B
*
* B) Conjoined Syllables (only covers modern Korean language)
* * U+AC00..U+D7AF ; Hangul Syllables
*
* C) Compatibility Jamo (one code-point for each "shape")
* * U+3130..U+318F ; Hangul Compatibility Jamo
*
* This modules helps you convert characters from one model to another.
* Primary functionalities are:
*
* 1) Convert from any encodings to Conjoining Jamo characters (A),
* e.g. for prefix matching
*
* 2) Convert from any encodings to Syllable characters, when possible (B),
* e.g. to reach the normal Unicode form (NFC)
*/
'use strict';
var HANGUL_COMPATIBILITY_OR_SYLLABLE_REGEX = /[\u3130-\u318F\uAC00-\uD7AF]/;
/**
* Returns true if the input includes any Hangul Compatibility Jamo or
* Hangul Conjoined Syllable.
*
* @param {string} str
*/
function hasCompatibilityOrSyllable(str) {
return HANGUL_COMPATIBILITY_OR_SYLLABLE_REGEX.test(str);
}
/* Compatibility Jamo -> Conjoining Jamo
*
* Maps a compatibility character to the Conjoining Jamo character,
* positioned at (compatibilityCodePoint - 0x3131).
*
* Generated by:
* $ grep '^31[3-8].;' UnicodeData.txt |\
* awk -F';' '{print $6}' | awk '{print " 0x"$2","}'
*/
var CMAP = [0x1100, 0x1101, 0x11AA, 0x1102, 0x11AC, 0x11AD, 0x1103, 0x1104, 0x1105, 0x11B0, 0x11B1, 0x11B2, 0x11B3, 0x11B4, 0x11B5, 0x111A, 0x1106, 0x1107, 0x1108, 0x1121, 0x1109, 0x110A, 0x110B, 0x110C, 0x110D, 0x110E, 0x110F, 0x1110, 0x1111, 0x1112, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, 0x116A, 0x116B, 0x116C, 0x116D, 0x116E, 0x116F, 0x1170, 0x1171, 0x1172, 0x1173, 0x1174, 0x1175, 0x1160, 0x1114, 0x1115, 0x11C7, 0x11C8, 0x11CC, 0x11CE, 0x11D3, 0x11D7, 0x11D9, 0x111C, 0x11DD, 0x11DF, 0x111D, 0x111E, 0x1120, 0x1122, 0x1123, 0x1127, 0x1129, 0x112B, 0x112C, 0x112D, 0x112E, 0x112F, 0x1132, 0x1136, 0x1140, 0x1147, 0x114C, 0x11F1, 0x11F2, 0x1157, 0x1158, 0x1159, 0x1184, 0x1185, 0x1188, 0x1191, 0x1192, 0x1194, 0x119E, 0x11A1];
var CBASE = 0x3131;
var CCOUNT = CMAP.length;
var CTOP = CBASE + CCOUNT;
/**
* Maps one Hangul Compatibility Jamo code-point to the equivalent Hangul
* Conjoining Jamo characters, as defined in UnicodeData.txt.
*
* @param {number} codePoint One Unicode code-point
* @output {string}
*/
function fromCompatibility(codePoint) {
return String.fromCharCode(CMAP[codePoint - CBASE]);
}
/**
* Conjoined Syllable -> Conjoining Jamo
*
* Based on the "Hangul Syllable Decomposition" algorithm provided in
* 3.12 Conjoining Jamo Behavior, The Unicode Standard, Version 6.3.0.
* <http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf>
*/
var LBASE = 0x1100;
var VBASE = 0x1161;
var TBASE = 0x11A7;
var SBASE = 0xAC00;
var LCOUNT = 19;
var VCOUNT = 21;
var TCOUNT = 28;
var NCOUNT = VCOUNT * TCOUNT;
var SCOUNT = LCOUNT * NCOUNT;
var STOP = SBASE + SCOUNT;
/**
* Maps one Hangul Syllable code-point to the equivalent Hangul
* Conjoining Jamo characters, as defined in UnicodeData.txt.
*
* @param {number} codePoint One Unicode character
* @output {string}
*/
function decomposeSyllable(codePoint) {
var sylSIndex = codePoint - SBASE;
var sylTIndex = sylSIndex % TCOUNT;
return String.fromCharCode(LBASE + sylSIndex / NCOUNT) + String.fromCharCode(VBASE + sylSIndex % NCOUNT / TCOUNT) + (sylTIndex > 0 ? String.fromCharCode(TBASE + sylTIndex) : '');
}
/* To Conjoining Jamo */
/**
* Return Unicode characters as they are, except for Hangul characters, which
* will be converted to the Conjoining Jamo form.
*
* @param {string} string
* @output {string}
*/
function toConjoiningJamo(string) {
if (!hasCompatibilityOrSyllable(string)) {
return string;
}
var result = [];
for (var i = 0; i < string.length; i++) {
var charStr = string.charAt(i);
var codeUnit = charStr.charCodeAt(0);
result.push(CBASE <= codeUnit && codeUnit < CTOP ? fromCompatibility(codeUnit) : SBASE <= codeUnit && codeUnit < STOP ? decomposeSyllable(codeUnit) : charStr);
}
return result.join('');
}
var UnicodeHangulKorean = {
toConjoiningJamo: toConjoiningJamo
};
module.exports = UnicodeHangulKorean;

View File

@@ -0,0 +1,137 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UnicodeHangulKorean
* @typechecks
*/
/**
* Unicode algorithms for Hangul script, the Korean writing system
*
* Hangul script has three encoded models in Unicode:
*
* A) Conjoining Jamo (covers modern and historic elements)
* * U+1100..U+11FF ; Hangul Jamo
* * U+A960..U+A97F ; Hangul Jamo Extended-A
* * U+D7B0..U+D7FF ; Hangul Jamo Extended-B
*
* B) Conjoined Syllables (only covers modern Korean language)
* * U+AC00..U+D7AF ; Hangul Syllables
*
* C) Compatibility Jamo (one code-point for each "shape")
* * U+3130..U+318F ; Hangul Compatibility Jamo
*
* This modules helps you convert characters from one model to another.
* Primary functionalities are:
*
* 1) Convert from any encodings to Conjoining Jamo characters (A),
* e.g. for prefix matching
*
* 2) Convert from any encodings to Syllable characters, when possible (B),
* e.g. to reach the normal Unicode form (NFC)
*/
'use strict';
const HANGUL_COMPATIBILITY_OR_SYLLABLE_REGEX = /[\u3130-\u318F\uAC00-\uD7AF]/;
/**
* Returns true if the input includes any Hangul Compatibility Jamo or
* Hangul Conjoined Syllable.
*
* @param {string} str
*/
function hasCompatibilityOrSyllable(str) {
return HANGUL_COMPATIBILITY_OR_SYLLABLE_REGEX.test(str);
}
/* Compatibility Jamo -> Conjoining Jamo
*
* Maps a compatibility character to the Conjoining Jamo character,
* positioned at (compatibilityCodePoint - 0x3131).
*
* Generated by:
* $ grep '^31[3-8].;' UnicodeData.txt |\
* awk -F';' '{print $6}' | awk '{print " 0x"$2","}'
*/
const CMAP = [0x1100, 0x1101, 0x11AA, 0x1102, 0x11AC, 0x11AD, 0x1103, 0x1104, 0x1105, 0x11B0, 0x11B1, 0x11B2, 0x11B3, 0x11B4, 0x11B5, 0x111A, 0x1106, 0x1107, 0x1108, 0x1121, 0x1109, 0x110A, 0x110B, 0x110C, 0x110D, 0x110E, 0x110F, 0x1110, 0x1111, 0x1112, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, 0x116A, 0x116B, 0x116C, 0x116D, 0x116E, 0x116F, 0x1170, 0x1171, 0x1172, 0x1173, 0x1174, 0x1175, 0x1160, 0x1114, 0x1115, 0x11C7, 0x11C8, 0x11CC, 0x11CE, 0x11D3, 0x11D7, 0x11D9, 0x111C, 0x11DD, 0x11DF, 0x111D, 0x111E, 0x1120, 0x1122, 0x1123, 0x1127, 0x1129, 0x112B, 0x112C, 0x112D, 0x112E, 0x112F, 0x1132, 0x1136, 0x1140, 0x1147, 0x114C, 0x11F1, 0x11F2, 0x1157, 0x1158, 0x1159, 0x1184, 0x1185, 0x1188, 0x1191, 0x1192, 0x1194, 0x119E, 0x11A1];
const CBASE = 0x3131;
const CCOUNT = CMAP.length;
const CTOP = CBASE + CCOUNT;
/**
* Maps one Hangul Compatibility Jamo code-point to the equivalent Hangul
* Conjoining Jamo characters, as defined in UnicodeData.txt.
*
* @param {number} codePoint One Unicode code-point
* @output {string}
*/
function fromCompatibility(codePoint) {
return String.fromCharCode(CMAP[codePoint - CBASE]);
}
/**
* Conjoined Syllable -> Conjoining Jamo
*
* Based on the "Hangul Syllable Decomposition" algorithm provided in
* 3.12 Conjoining Jamo Behavior, The Unicode Standard, Version 6.3.0.
* <http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf>
*/
const LBASE = 0x1100;
const VBASE = 0x1161;
const TBASE = 0x11A7;
const SBASE = 0xAC00;
const LCOUNT = 19;
const VCOUNT = 21;
const TCOUNT = 28;
const NCOUNT = VCOUNT * TCOUNT;
const SCOUNT = LCOUNT * NCOUNT;
const STOP = SBASE + SCOUNT;
/**
* Maps one Hangul Syllable code-point to the equivalent Hangul
* Conjoining Jamo characters, as defined in UnicodeData.txt.
*
* @param {number} codePoint One Unicode character
* @output {string}
*/
function decomposeSyllable(codePoint) {
const sylSIndex = codePoint - SBASE;
const sylTIndex = sylSIndex % TCOUNT;
return String.fromCharCode(LBASE + sylSIndex / NCOUNT) + String.fromCharCode(VBASE + sylSIndex % NCOUNT / TCOUNT) + (sylTIndex > 0 ? String.fromCharCode(TBASE + sylTIndex) : '');
}
/* To Conjoining Jamo */
/**
* Return Unicode characters as they are, except for Hangul characters, which
* will be converted to the Conjoining Jamo form.
*
* @param {string} string
* @output {string}
*/
function toConjoiningJamo(string) {
if (!hasCompatibilityOrSyllable(string)) {
return string;
}
const result = [];
for (let i = 0; i < string.length; i++) {
const charStr = string.charAt(i);
const codeUnit = charStr.charCodeAt(0);
result.push(CBASE <= codeUnit && codeUnit < CTOP ? fromCompatibility(codeUnit) : SBASE <= codeUnit && codeUnit < STOP ? decomposeSyllable(codeUnit) : charStr);
}
return result.join('');
}
const UnicodeHangulKorean = {
toConjoiningJamo: toConjoiningJamo
};
module.exports = UnicodeHangulKorean;

View File

@@ -0,0 +1,228 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/**
* Unicode-enabled replacesments for basic String functions.
*
* All the functions in this module assume that the input string is a valid
* UTF-16 encoding of a Unicode sequence. If it's not the case, the behavior
* will be undefined.
*
* WARNING: Since this module is typechecks-enforced, you may find new bugs
* when replacing normal String functions with ones provided here.
*/
'use strict';
var invariant = require("./invariant"); // These two ranges are consecutive so anything in [HIGH_START, LOW_END] is a
// surrogate code unit.
var SURROGATE_HIGH_START = 0xD800;
var SURROGATE_HIGH_END = 0xDBFF;
var SURROGATE_LOW_START = 0xDC00;
var SURROGATE_LOW_END = 0xDFFF;
var SURROGATE_UNITS_REGEX = /[\uD800-\uDFFF]/;
/**
* @param {number} codeUnit A Unicode code-unit, in range [0, 0x10FFFF]
* @return {boolean} Whether code-unit is in a surrogate (hi/low) range
*/
function isCodeUnitInSurrogateRange(codeUnit) {
return SURROGATE_HIGH_START <= codeUnit && codeUnit <= SURROGATE_LOW_END;
}
/**
* Returns whether the two characters starting at `index` form a surrogate pair.
* For example, given the string s = "\uD83D\uDE0A", (s, 0) returns true and
* (s, 1) returns false.
*
* @param {string} str
* @param {number} index
* @return {boolean}
*/
function isSurrogatePair(str, index) {
!(0 <= index && index < str.length) ? process.env.NODE_ENV !== "production" ? invariant(false, 'isSurrogatePair: Invalid index %s for string length %s.', index, str.length) : invariant(false) : void 0;
if (index + 1 === str.length) {
return false;
}
var first = str.charCodeAt(index);
var second = str.charCodeAt(index + 1);
return SURROGATE_HIGH_START <= first && first <= SURROGATE_HIGH_END && SURROGATE_LOW_START <= second && second <= SURROGATE_LOW_END;
}
/**
* @param {string} str Non-empty string
* @return {boolean} True if the input includes any surrogate code units
*/
function hasSurrogateUnit(str) {
return SURROGATE_UNITS_REGEX.test(str);
}
/**
* Return the length of the original Unicode character at given position in the
* String by looking into the UTF-16 code unit; that is equal to 1 for any
* non-surrogate characters in BMP ([U+0000..U+D7FF] and [U+E000, U+FFFF]); and
* returns 2 for the hi/low surrogates ([U+D800..U+DFFF]), which are in fact
* representing non-BMP characters ([U+10000..U+10FFFF]).
*
* Examples:
* - '\u0020' => 1
* - '\u3020' => 1
* - '\uD835' => 2
* - '\uD835\uDDEF' => 2
* - '\uDDEF' => 2
*
* @param {string} str Non-empty string
* @param {number} pos Position in the string to look for one code unit
* @return {number} Number 1 or 2
*/
function getUTF16Length(str, pos) {
return 1 + isCodeUnitInSurrogateRange(str.charCodeAt(pos));
}
/**
* Fully Unicode-enabled replacement for String#length
*
* @param {string} str Valid Unicode string
* @return {number} The number of Unicode characters in the string
*/
function strlen(str) {
// Call the native functions if there's no surrogate char
if (!hasSurrogateUnit(str)) {
return str.length;
}
var len = 0;
for (var pos = 0; pos < str.length; pos += getUTF16Length(str, pos)) {
len++;
}
return len;
}
/**
* Fully Unicode-enabled replacement for String#substr()
*
* @param {string} str Valid Unicode string
* @param {number} start Location in Unicode sequence to begin extracting
* @param {?number} length The number of Unicode characters to extract
* (default: to the end of the string)
* @return {string} Extracted sub-string
*/
function substr(str, start, length) {
start = start || 0;
length = length === undefined ? Infinity : length || 0; // Call the native functions if there's no surrogate char
if (!hasSurrogateUnit(str)) {
return str.substr(start, length);
} // Obvious cases
var size = str.length;
if (size <= 0 || start > size || length <= 0) {
return '';
} // Find the actual starting position
var posA = 0;
if (start > 0) {
for (; start > 0 && posA < size; start--) {
posA += getUTF16Length(str, posA);
}
if (posA >= size) {
return '';
}
} else if (start < 0) {
for (posA = size; start < 0 && 0 < posA; start++) {
posA -= getUTF16Length(str, posA - 1);
}
if (posA < 0) {
posA = 0;
}
} // Find the actual ending position
var posB = size;
if (length < size) {
for (posB = posA; length > 0 && posB < size; length--) {
posB += getUTF16Length(str, posB);
}
}
return str.substring(posA, posB);
}
/**
* Fully Unicode-enabled replacement for String#substring()
*
* @param {string} str Valid Unicode string
* @param {number} start Location in Unicode sequence to begin extracting
* @param {?number} end Location in Unicode sequence to end extracting
* (default: end of the string)
* @return {string} Extracted sub-string
*/
function substring(str, start, end) {
start = start || 0;
end = end === undefined ? Infinity : end || 0;
if (start < 0) {
start = 0;
}
if (end < 0) {
end = 0;
}
var length = Math.abs(end - start);
start = start < end ? start : end;
return substr(str, start, length);
}
/**
* Get a list of Unicode code-points from a String
*
* @param {string} str Valid Unicode string
* @return {array<number>} A list of code-points in [0..0x10FFFF]
*/
function getCodePoints(str) {
var codePoints = [];
for (var pos = 0; pos < str.length; pos += getUTF16Length(str, pos)) {
codePoints.push(str.codePointAt(pos));
}
return codePoints;
}
var UnicodeUtils = {
getCodePoints: getCodePoints,
getUTF16Length: getUTF16Length,
hasSurrogateUnit: hasSurrogateUnit,
isCodeUnitInSurrogateRange: isCodeUnitInSurrogateRange,
isSurrogatePair: isSurrogatePair,
strlen: strlen,
substring: substring,
substr: substr
};
module.exports = UnicodeUtils;

View File

@@ -0,0 +1,229 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UnicodeUtils
* @typechecks
*/
/**
* Unicode-enabled replacesments for basic String functions.
*
* All the functions in this module assume that the input string is a valid
* UTF-16 encoding of a Unicode sequence. If it's not the case, the behavior
* will be undefined.
*
* WARNING: Since this module is typechecks-enforced, you may find new bugs
* when replacing normal String functions with ones provided here.
*/
'use strict';
const invariant = require("./invariant"); // These two ranges are consecutive so anything in [HIGH_START, LOW_END] is a
// surrogate code unit.
const SURROGATE_HIGH_START = 0xD800;
const SURROGATE_HIGH_END = 0xDBFF;
const SURROGATE_LOW_START = 0xDC00;
const SURROGATE_LOW_END = 0xDFFF;
const SURROGATE_UNITS_REGEX = /[\uD800-\uDFFF]/;
/**
* @param {number} codeUnit A Unicode code-unit, in range [0, 0x10FFFF]
* @return {boolean} Whether code-unit is in a surrogate (hi/low) range
*/
function isCodeUnitInSurrogateRange(codeUnit) {
return SURROGATE_HIGH_START <= codeUnit && codeUnit <= SURROGATE_LOW_END;
}
/**
* Returns whether the two characters starting at `index` form a surrogate pair.
* For example, given the string s = "\uD83D\uDE0A", (s, 0) returns true and
* (s, 1) returns false.
*
* @param {string} str
* @param {number} index
* @return {boolean}
*/
function isSurrogatePair(str, index) {
invariant(0 <= index && index < str.length, 'isSurrogatePair: Invalid index %s for string length %s.', index, str.length);
if (index + 1 === str.length) {
return false;
}
const first = str.charCodeAt(index);
const second = str.charCodeAt(index + 1);
return SURROGATE_HIGH_START <= first && first <= SURROGATE_HIGH_END && SURROGATE_LOW_START <= second && second <= SURROGATE_LOW_END;
}
/**
* @param {string} str Non-empty string
* @return {boolean} True if the input includes any surrogate code units
*/
function hasSurrogateUnit(str) {
return SURROGATE_UNITS_REGEX.test(str);
}
/**
* Return the length of the original Unicode character at given position in the
* String by looking into the UTF-16 code unit; that is equal to 1 for any
* non-surrogate characters in BMP ([U+0000..U+D7FF] and [U+E000, U+FFFF]); and
* returns 2 for the hi/low surrogates ([U+D800..U+DFFF]), which are in fact
* representing non-BMP characters ([U+10000..U+10FFFF]).
*
* Examples:
* - '\u0020' => 1
* - '\u3020' => 1
* - '\uD835' => 2
* - '\uD835\uDDEF' => 2
* - '\uDDEF' => 2
*
* @param {string} str Non-empty string
* @param {number} pos Position in the string to look for one code unit
* @return {number} Number 1 or 2
*/
function getUTF16Length(str, pos) {
return 1 + isCodeUnitInSurrogateRange(str.charCodeAt(pos));
}
/**
* Fully Unicode-enabled replacement for String#length
*
* @param {string} str Valid Unicode string
* @return {number} The number of Unicode characters in the string
*/
function strlen(str) {
// Call the native functions if there's no surrogate char
if (!hasSurrogateUnit(str)) {
return str.length;
}
let len = 0;
for (let pos = 0; pos < str.length; pos += getUTF16Length(str, pos)) {
len++;
}
return len;
}
/**
* Fully Unicode-enabled replacement for String#substr()
*
* @param {string} str Valid Unicode string
* @param {number} start Location in Unicode sequence to begin extracting
* @param {?number} length The number of Unicode characters to extract
* (default: to the end of the string)
* @return {string} Extracted sub-string
*/
function substr(str, start, length) {
start = start || 0;
length = length === undefined ? Infinity : length || 0; // Call the native functions if there's no surrogate char
if (!hasSurrogateUnit(str)) {
return str.substr(start, length);
} // Obvious cases
const size = str.length;
if (size <= 0 || start > size || length <= 0) {
return '';
} // Find the actual starting position
let posA = 0;
if (start > 0) {
for (; start > 0 && posA < size; start--) {
posA += getUTF16Length(str, posA);
}
if (posA >= size) {
return '';
}
} else if (start < 0) {
for (posA = size; start < 0 && 0 < posA; start++) {
posA -= getUTF16Length(str, posA - 1);
}
if (posA < 0) {
posA = 0;
}
} // Find the actual ending position
let posB = size;
if (length < size) {
for (posB = posA; length > 0 && posB < size; length--) {
posB += getUTF16Length(str, posB);
}
}
return str.substring(posA, posB);
}
/**
* Fully Unicode-enabled replacement for String#substring()
*
* @param {string} str Valid Unicode string
* @param {number} start Location in Unicode sequence to begin extracting
* @param {?number} end Location in Unicode sequence to end extracting
* (default: end of the string)
* @return {string} Extracted sub-string
*/
function substring(str, start, end) {
start = start || 0;
end = end === undefined ? Infinity : end || 0;
if (start < 0) {
start = 0;
}
if (end < 0) {
end = 0;
}
const length = Math.abs(end - start);
start = start < end ? start : end;
return substr(str, start, length);
}
/**
* Get a list of Unicode code-points from a String
*
* @param {string} str Valid Unicode string
* @return {array<number>} A list of code-points in [0..0x10FFFF]
*/
function getCodePoints(str) {
const codePoints = [];
for (let pos = 0; pos < str.length; pos += getUTF16Length(str, pos)) {
codePoints.push(str.codePointAt(pos));
}
return codePoints;
}
const UnicodeUtils = {
getCodePoints: getCodePoints,
getUTF16Length: getUTF16Length,
hasSurrogateUnit: hasSurrogateUnit,
isCodeUnitInSurrogateRange: isCodeUnitInSurrogateRange,
isSurrogatePair: isSurrogatePair,
strlen: strlen,
substring: substring,
substr: substr
};
module.exports = UnicodeUtils;

View File

@@ -0,0 +1,240 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
/**
* Unicode-enabled extra utility functions not always needed.
*/
'use strict';
var UnicodeUtils = require("./UnicodeUtils");
/**
* @param {number} codePoint Valid Unicode code-point
* @param {number} len Zero-padded minimum width of result
* @return {string} A zero-padded hexadecimal string (00XXXX)
*/
function zeroPaddedHex(codePoint, len) {
var codePointHex = codePoint.toString(16).toUpperCase();
var numZeros = Math.max(0, len - codePointHex.length);
var result = '';
for (var i = 0; i < numZeros; i++) {
result += '0';
}
result += codePointHex;
return result;
}
/**
* @param {number} codePoint Valid Unicode code-point
* @return {string} A formatted Unicode code-point string
* of the format U+XXXX, U+XXXXX, or U+XXXXXX
*/
function formatCodePoint(codePoint) {
codePoint = codePoint || 0; // NaN --> 0
var formatted = '';
if (codePoint <= 0xFFFF) {
formatted = zeroPaddedHex(codePoint, 4);
} else {
formatted = codePoint.toString(16).toUpperCase();
}
return 'U+' + formatted;
}
/**
* Get a list of formatted (string) Unicode code-points from a String
*
* @param {string} str Valid Unicode string
* @return {array<string>} A list of formatted code-point strings
*/
function getCodePointsFormatted(str) {
var codePoints = UnicodeUtils.getCodePoints(str);
return codePoints.map(formatCodePoint);
}
var specialEscape = {
0x07: '\\a',
0x08: '\\b',
0x0C: '\\f',
0x0A: '\\n',
0x0D: '\\r',
0x09: '\\t',
0x0B: '\\v',
0x22: '\\"',
0x5c: '\\\\'
};
/**
* Returns a double-quoted PHP string with all non-printable and
* non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function phpEscape(s) {
var result = '"';
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = UnicodeUtils.getCodePoints(s)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var cp = _step.value;
var special = specialEscape[cp];
if (special !== undefined) {
result += special;
} else if (cp >= 0x20 && cp <= 0x7e) {
result += String.fromCodePoint(cp);
} else if (cp <= 0xFFFF) {
result += "\\u{" + zeroPaddedHex(cp, 4) + '}';
} else {
result += "\\u{" + zeroPaddedHex(cp, 6) + '}';
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
result += '"';
return result;
}
/**
* Returns a double-quoted Java or JavaScript string with all
* non-printable and non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function jsEscape(s) {
var result = '"';
for (var i = 0; i < s.length; i++) {
var cp = s.charCodeAt(i);
var special = specialEscape[cp];
if (special !== undefined) {
result += special;
} else if (cp >= 0x20 && cp <= 0x7e) {
result += String.fromCodePoint(cp);
} else {
result += "\\u" + zeroPaddedHex(cp, 4);
}
}
result += '"';
return result;
}
function c11Escape(s) {
var result = '';
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = UnicodeUtils.getCodePoints(s)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var cp = _step2.value;
var special = specialEscape[cp];
if (special !== undefined) {
result += special;
} else if (cp >= 0x20 && cp <= 0x7e) {
result += String.fromCodePoint(cp);
} else if (cp <= 0xFFFF) {
result += "\\u" + zeroPaddedHex(cp, 4);
} else {
result += "\\U" + zeroPaddedHex(cp, 8);
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2["return"] != null) {
_iterator2["return"]();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return result;
}
/**
* Returns a double-quoted C string with all non-printable and
* non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function cEscape(s) {
return 'u8"' + c11Escape(s) + '"';
}
/**
* Returns a double-quoted Objective-C string with all non-printable
* and non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function objcEscape(s) {
return '@"' + c11Escape(s) + '"';
}
/**
* Returns a double-quoted Python string with all non-printable
* and non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function pyEscape(s) {
return 'u"' + c11Escape(s) + '"';
}
var UnicodeUtilsExtra = {
formatCodePoint: formatCodePoint,
getCodePointsFormatted: getCodePointsFormatted,
zeroPaddedHex: zeroPaddedHex,
phpEscape: phpEscape,
jsEscape: jsEscape,
cEscape: cEscape,
objcEscape: objcEscape,
pyEscape: pyEscape
};
module.exports = UnicodeUtilsExtra;

View File

@@ -0,0 +1,203 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UnicodeUtilsExtra
* @typechecks
*/
/**
* Unicode-enabled extra utility functions not always needed.
*/
'use strict';
const UnicodeUtils = require("./UnicodeUtils");
/**
* @param {number} codePoint Valid Unicode code-point
* @param {number} len Zero-padded minimum width of result
* @return {string} A zero-padded hexadecimal string (00XXXX)
*/
function zeroPaddedHex(codePoint, len) {
let codePointHex = codePoint.toString(16).toUpperCase();
let numZeros = Math.max(0, len - codePointHex.length);
var result = '';
for (var i = 0; i < numZeros; i++) {
result += '0';
}
result += codePointHex;
return result;
}
/**
* @param {number} codePoint Valid Unicode code-point
* @return {string} A formatted Unicode code-point string
* of the format U+XXXX, U+XXXXX, or U+XXXXXX
*/
function formatCodePoint(codePoint) {
codePoint = codePoint || 0; // NaN --> 0
var formatted = '';
if (codePoint <= 0xFFFF) {
formatted = zeroPaddedHex(codePoint, 4);
} else {
formatted = codePoint.toString(16).toUpperCase();
}
return 'U+' + formatted;
}
/**
* Get a list of formatted (string) Unicode code-points from a String
*
* @param {string} str Valid Unicode string
* @return {array<string>} A list of formatted code-point strings
*/
function getCodePointsFormatted(str) {
const codePoints = UnicodeUtils.getCodePoints(str);
return codePoints.map(formatCodePoint);
}
const specialEscape = {
0x07: '\\a',
0x08: '\\b',
0x0C: '\\f',
0x0A: '\\n',
0x0D: '\\r',
0x09: '\\t',
0x0B: '\\v',
0x22: '\\"',
0x5c: '\\\\'
};
/**
* Returns a double-quoted PHP string with all non-printable and
* non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function phpEscape(s) {
var result = '"';
for (let cp of UnicodeUtils.getCodePoints(s)) {
let special = specialEscape[cp];
if (special !== undefined) {
result += special;
} else if (cp >= 0x20 && cp <= 0x7e) {
result += String.fromCodePoint(cp);
} else if (cp <= 0xFFFF) {
result += '\\u{' + zeroPaddedHex(cp, 4) + '}';
} else {
result += '\\u{' + zeroPaddedHex(cp, 6) + '}';
}
}
result += '"';
return result;
}
/**
* Returns a double-quoted Java or JavaScript string with all
* non-printable and non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function jsEscape(s) {
var result = '"';
for (var i = 0; i < s.length; i++) {
let cp = s.charCodeAt(i);
let special = specialEscape[cp];
if (special !== undefined) {
result += special;
} else if (cp >= 0x20 && cp <= 0x7e) {
result += String.fromCodePoint(cp);
} else {
result += '\\u' + zeroPaddedHex(cp, 4);
}
}
result += '"';
return result;
}
function c11Escape(s) {
var result = '';
for (let cp of UnicodeUtils.getCodePoints(s)) {
let special = specialEscape[cp];
if (special !== undefined) {
result += special;
} else if (cp >= 0x20 && cp <= 0x7e) {
result += String.fromCodePoint(cp);
} else if (cp <= 0xFFFF) {
result += '\\u' + zeroPaddedHex(cp, 4);
} else {
result += '\\U' + zeroPaddedHex(cp, 8);
}
}
return result;
}
/**
* Returns a double-quoted C string with all non-printable and
* non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function cEscape(s) {
return 'u8"' + c11Escape(s) + '"';
}
/**
* Returns a double-quoted Objective-C string with all non-printable
* and non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function objcEscape(s) {
return '@"' + c11Escape(s) + '"';
}
/**
* Returns a double-quoted Python string with all non-printable
* and non-US-ASCII sequences escaped.
*
* @param {string} str Valid Unicode string
* @return {string} Double-quoted string with Unicode sequences escaped
*/
function pyEscape(s) {
return 'u"' + c11Escape(s) + '"';
}
const UnicodeUtilsExtra = {
formatCodePoint: formatCodePoint,
getCodePointsFormatted: getCodePointsFormatted,
zeroPaddedHex: zeroPaddedHex,
phpEscape: phpEscape,
jsEscape: jsEscape,
cEscape: cEscape,
objcEscape: objcEscape,
pyEscape: pyEscape
};
module.exports = UnicodeUtilsExtra;

View File

@@ -0,0 +1,238 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use strict';
var UserAgentData = require("./UserAgentData");
var VersionRange = require("./VersionRange");
var mapObject = require("./mapObject");
var memoizeStringOnly = require("./memoizeStringOnly");
/**
* Checks to see whether `name` and `version` satisfy `query`.
*
* @param {string} name Name of the browser, device, engine or platform
* @param {?string} version Version of the browser, engine or platform
* @param {string} query Query of form "Name [range expression]"
* @param {?function} normalizer Optional pre-processor for range expression
* @return {boolean}
*/
function compare(name, version, query, normalizer) {
// check for exact match with no version
if (name === query) {
return true;
} // check for non-matching names
if (!query.startsWith(name)) {
return false;
} // full comparison with version
var range = query.slice(name.length);
if (version) {
range = normalizer ? normalizer(range) : range;
return VersionRange.contains(range, version);
}
return false;
}
/**
* Normalizes `version` by stripping any "NT" prefix, but only on the Windows
* platform.
*
* Mimics the stripping performed by the `UserAgentWindowsPlatform` PHP class.
*
* @param {string} version
* @return {string}
*/
function normalizePlatformVersion(version) {
if (UserAgentData.platformName === 'Windows') {
return version.replace(/^\s*NT/, '');
}
return version;
}
/**
* Provides client-side access to the authoritative PHP-generated User Agent
* information supplied by the server.
*/
var UserAgent = {
/**
* Check if the User Agent browser matches `query`.
*
* `query` should be a string like "Chrome" or "Chrome > 33".
*
* Valid browser names include:
*
* - ACCESS NetFront
* - AOL
* - Amazon Silk
* - Android
* - BlackBerry
* - BlackBerry PlayBook
* - Chrome
* - Chrome for iOS
* - Chrome frame
* - Facebook PHP SDK
* - Facebook for iOS
* - Firefox
* - IE
* - IE Mobile
* - Mobile Safari
* - Motorola Internet Browser
* - Nokia
* - Openwave Mobile Browser
* - Opera
* - Opera Mini
* - Opera Mobile
* - Safari
* - UIWebView
* - Unknown
* - webOS
* - etc...
*
* An authoritative list can be found in the PHP `BrowserDetector` class and
* related classes in the same file (see calls to `new UserAgentBrowser` here:
* https://fburl.com/50728104).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name [range expression]"
* @return {boolean}
*/
isBrowser: function isBrowser(query) {
return compare(UserAgentData.browserName, UserAgentData.browserFullVersion, query);
},
/**
* Check if the User Agent browser uses a 32 or 64 bit architecture.
*
* @note Function results are memoized
*
* @param {string} query Query of the form "32" or "64".
* @return {boolean}
*/
isBrowserArchitecture: function isBrowserArchitecture(query) {
return compare(UserAgentData.browserArchitecture, null, query);
},
/**
* Check if the User Agent device matches `query`.
*
* `query` should be a string like "iPhone" or "iPad".
*
* Valid device names include:
*
* - Kindle
* - Kindle Fire
* - Unknown
* - iPad
* - iPhone
* - iPod
* - etc...
*
* An authoritative list can be found in the PHP `DeviceDetector` class and
* related classes in the same file (see calls to `new UserAgentDevice` here:
* https://fburl.com/50728332).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name"
* @return {boolean}
*/
isDevice: function isDevice(query) {
return compare(UserAgentData.deviceName, null, query);
},
/**
* Check if the User Agent rendering engine matches `query`.
*
* `query` should be a string like "WebKit" or "WebKit >= 537".
*
* Valid engine names include:
*
* - Gecko
* - Presto
* - Trident
* - WebKit
* - etc...
*
* An authoritative list can be found in the PHP `RenderingEngineDetector`
* class related classes in the same file (see calls to `new
* UserAgentRenderingEngine` here: https://fburl.com/50728617).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name [range expression]"
* @return {boolean}
*/
isEngine: function isEngine(query) {
return compare(UserAgentData.engineName, UserAgentData.engineVersion, query);
},
/**
* Check if the User Agent platform matches `query`.
*
* `query` should be a string like "Windows" or "iOS 5 - 6".
*
* Valid platform names include:
*
* - Android
* - BlackBerry OS
* - Java ME
* - Linux
* - Mac OS X
* - Mac OS X Calendar
* - Mac OS X Internet Account
* - Symbian
* - SymbianOS
* - Windows
* - Windows Mobile
* - Windows Phone
* - iOS
* - iOS Facebook Integration Account
* - iOS Facebook Social Sharing UI
* - webOS
* - Chrome OS
* - etc...
*
* An authoritative list can be found in the PHP `PlatformDetector` class and
* related classes in the same file (see calls to `new UserAgentPlatform`
* here: https://fburl.com/50729226).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name [range expression]"
* @return {boolean}
*/
isPlatform: function isPlatform(query) {
return compare(UserAgentData.platformName, UserAgentData.platformFullVersion, query, normalizePlatformVersion);
},
/**
* Check if the User Agent platform is a 32 or 64 bit architecture.
*
* @note Function results are memoized
*
* @param {string} query Query of the form "32" or "64".
* @return {boolean}
*/
isPlatformArchitecture: function isPlatformArchitecture(query) {
return compare(UserAgentData.platformArchitecture, null, query);
}
};
module.exports = mapObject(UserAgent, memoizeStringOnly);

View File

@@ -0,0 +1,240 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UserAgent
*/
'use strict';
const UserAgentData = require("./UserAgentData");
const VersionRange = require("./VersionRange");
const mapObject = require("./mapObject");
const memoizeStringOnly = require("./memoizeStringOnly");
/**
* Checks to see whether `name` and `version` satisfy `query`.
*
* @param {string} name Name of the browser, device, engine or platform
* @param {?string} version Version of the browser, engine or platform
* @param {string} query Query of form "Name [range expression]"
* @param {?function} normalizer Optional pre-processor for range expression
* @return {boolean}
*/
function compare(name, version, query, normalizer) {
// check for exact match with no version
if (name === query) {
return true;
} // check for non-matching names
if (!query.startsWith(name)) {
return false;
} // full comparison with version
let range = query.slice(name.length);
if (version) {
range = normalizer ? normalizer(range) : range;
return VersionRange.contains(range, version);
}
return false;
}
/**
* Normalizes `version` by stripping any "NT" prefix, but only on the Windows
* platform.
*
* Mimics the stripping performed by the `UserAgentWindowsPlatform` PHP class.
*
* @param {string} version
* @return {string}
*/
function normalizePlatformVersion(version) {
if (UserAgentData.platformName === 'Windows') {
return version.replace(/^\s*NT/, '');
}
return version;
}
/**
* Provides client-side access to the authoritative PHP-generated User Agent
* information supplied by the server.
*/
const UserAgent = {
/**
* Check if the User Agent browser matches `query`.
*
* `query` should be a string like "Chrome" or "Chrome > 33".
*
* Valid browser names include:
*
* - ACCESS NetFront
* - AOL
* - Amazon Silk
* - Android
* - BlackBerry
* - BlackBerry PlayBook
* - Chrome
* - Chrome for iOS
* - Chrome frame
* - Facebook PHP SDK
* - Facebook for iOS
* - Firefox
* - IE
* - IE Mobile
* - Mobile Safari
* - Motorola Internet Browser
* - Nokia
* - Openwave Mobile Browser
* - Opera
* - Opera Mini
* - Opera Mobile
* - Safari
* - UIWebView
* - Unknown
* - webOS
* - etc...
*
* An authoritative list can be found in the PHP `BrowserDetector` class and
* related classes in the same file (see calls to `new UserAgentBrowser` here:
* https://fburl.com/50728104).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name [range expression]"
* @return {boolean}
*/
isBrowser(query) {
return compare(UserAgentData.browserName, UserAgentData.browserFullVersion, query);
},
/**
* Check if the User Agent browser uses a 32 or 64 bit architecture.
*
* @note Function results are memoized
*
* @param {string} query Query of the form "32" or "64".
* @return {boolean}
*/
isBrowserArchitecture(query) {
return compare(UserAgentData.browserArchitecture, null, query);
},
/**
* Check if the User Agent device matches `query`.
*
* `query` should be a string like "iPhone" or "iPad".
*
* Valid device names include:
*
* - Kindle
* - Kindle Fire
* - Unknown
* - iPad
* - iPhone
* - iPod
* - etc...
*
* An authoritative list can be found in the PHP `DeviceDetector` class and
* related classes in the same file (see calls to `new UserAgentDevice` here:
* https://fburl.com/50728332).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name"
* @return {boolean}
*/
isDevice(query) {
return compare(UserAgentData.deviceName, null, query);
},
/**
* Check if the User Agent rendering engine matches `query`.
*
* `query` should be a string like "WebKit" or "WebKit >= 537".
*
* Valid engine names include:
*
* - Gecko
* - Presto
* - Trident
* - WebKit
* - etc...
*
* An authoritative list can be found in the PHP `RenderingEngineDetector`
* class related classes in the same file (see calls to `new
* UserAgentRenderingEngine` here: https://fburl.com/50728617).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name [range expression]"
* @return {boolean}
*/
isEngine(query) {
return compare(UserAgentData.engineName, UserAgentData.engineVersion, query);
},
/**
* Check if the User Agent platform matches `query`.
*
* `query` should be a string like "Windows" or "iOS 5 - 6".
*
* Valid platform names include:
*
* - Android
* - BlackBerry OS
* - Java ME
* - Linux
* - Mac OS X
* - Mac OS X Calendar
* - Mac OS X Internet Account
* - Symbian
* - SymbianOS
* - Windows
* - Windows Mobile
* - Windows Phone
* - iOS
* - iOS Facebook Integration Account
* - iOS Facebook Social Sharing UI
* - webOS
* - Chrome OS
* - etc...
*
* An authoritative list can be found in the PHP `PlatformDetector` class and
* related classes in the same file (see calls to `new UserAgentPlatform`
* here: https://fburl.com/50729226).
*
* @note Function results are memoized
*
* @param {string} query Query of the form "Name [range expression]"
* @return {boolean}
*/
isPlatform(query) {
return compare(UserAgentData.platformName, UserAgentData.platformFullVersion, query, normalizePlatformVersion);
},
/**
* Check if the User Agent platform is a 32 or 64 bit architecture.
*
* @note Function results are memoized
*
* @param {string} query Query of the form "32" or "64".
* @return {boolean}
*/
isPlatformArchitecture(query) {
return compare(UserAgentData.platformArchitecture, null, query);
}
};
module.exports = mapObject(UserAgent, memoizeStringOnly);

View File

@@ -0,0 +1,79 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Usage note:
* This module makes a best effort to export the same data we would internally.
* At Facebook we use a server-generated module that does the parsing and
* exports the data for the client to use. We can't rely on a server-side
* implementation in open source so instead we make use of an open source
* library to do the heavy lifting and then make some adjustments as necessary.
* It's likely there will be some differences. Some we can smooth over.
* Others are going to be harder.
*/
'use strict';
var UAParser = require("ua-parser-js");
var UNKNOWN = 'Unknown';
var PLATFORM_MAP = {
'Mac OS': 'Mac OS X'
};
/**
* Convert from UAParser platform name to what we expect.
*/
function convertPlatformName(name) {
return PLATFORM_MAP[name] || name;
}
/**
* Get the version number in parts. This is very naive. We actually get major
* version as a part of UAParser already, which is generally good enough, but
* let's get the minor just in case.
*/
function getBrowserVersion(version) {
if (!version) {
return {
major: '',
minor: ''
};
}
var parts = version.split('.');
return {
major: parts[0],
minor: parts[1]
};
}
/**
* Get the UA data fom UAParser and then convert it to the format we're
* expecting for our APIS.
*/
var parser = new UAParser();
var results = parser.getResult(); // Do some conversion first.
var browserVersionData = getBrowserVersion(results.browser.version);
var uaData = {
browserArchitecture: results.cpu.architecture || UNKNOWN,
browserFullVersion: results.browser.version || UNKNOWN,
browserMinorVersion: browserVersionData.minor || UNKNOWN,
browserName: results.browser.name || UNKNOWN,
browserVersion: results.browser.major || UNKNOWN,
deviceName: results.device.model || UNKNOWN,
engineName: results.engine.name || UNKNOWN,
engineVersion: results.engine.version || UNKNOWN,
platformArchitecture: results.cpu.architecture || UNKNOWN,
platformName: convertPlatformName(results.os.name) || UNKNOWN,
platformVersion: results.os.version || UNKNOWN,
platformFullVersion: results.os.version || UNKNOWN
};
module.exports = uaData;

View File

@@ -0,0 +1,80 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UserAgentData
*/
/**
* Usage note:
* This module makes a best effort to export the same data we would internally.
* At Facebook we use a server-generated module that does the parsing and
* exports the data for the client to use. We can't rely on a server-side
* implementation in open source so instead we make use of an open source
* library to do the heavy lifting and then make some adjustments as necessary.
* It's likely there will be some differences. Some we can smooth over.
* Others are going to be harder.
*/
'use strict';
var UAParser = require("ua-parser-js");
var UNKNOWN = 'Unknown';
var PLATFORM_MAP = {
'Mac OS': 'Mac OS X'
};
/**
* Convert from UAParser platform name to what we expect.
*/
function convertPlatformName(name) {
return PLATFORM_MAP[name] || name;
}
/**
* Get the version number in parts. This is very naive. We actually get major
* version as a part of UAParser already, which is generally good enough, but
* let's get the minor just in case.
*/
function getBrowserVersion(version) {
if (!version) {
return {
major: '',
minor: ''
};
}
var parts = version.split('.');
return {
major: parts[0],
minor: parts[1]
};
}
/**
* Get the UA data fom UAParser and then convert it to the format we're
* expecting for our APIS.
*/
var parser = new UAParser();
var results = parser.getResult(); // Do some conversion first.
var browserVersionData = getBrowserVersion(results.browser.version);
var uaData = {
browserArchitecture: results.cpu.architecture || UNKNOWN,
browserFullVersion: results.browser.version || UNKNOWN,
browserMinorVersion: browserVersionData.minor || UNKNOWN,
browserName: results.browser.name || UNKNOWN,
browserVersion: results.browser.major || UNKNOWN,
deviceName: results.device.model || UNKNOWN,
engineName: results.engine.name || UNKNOWN,
engineVersion: results.engine.version || UNKNOWN,
platformArchitecture: results.cpu.architecture || UNKNOWN,
platformName: convertPlatformName(results.os.name) || UNKNOWN,
platformVersion: results.os.version || UNKNOWN,
platformFullVersion: results.os.version || UNKNOWN
};
module.exports = uaData;

View File

@@ -0,0 +1,396 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use strict';
var invariant = require("./invariant");
var componentRegex = /\./;
var orRegex = /\|\|/;
var rangeRegex = /\s+\-\s+/;
var modifierRegex = /^(<=|<|=|>=|~>|~|>|)?\s*(.+)/;
var numericRegex = /^(\d*)(.*)/;
/**
* Splits input `range` on "||" and returns true if any subrange matches
* `version`.
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
function checkOrExpression(range, version) {
var expressions = range.split(orRegex);
if (expressions.length > 1) {
return expressions.some(function (range) {
return VersionRange.contains(range, version);
});
} else {
range = expressions[0].trim();
return checkRangeExpression(range, version);
}
}
/**
* Splits input `range` on " - " (the surrounding whitespace is required) and
* returns true if version falls between the two operands.
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
function checkRangeExpression(range, version) {
var expressions = range.split(rangeRegex);
!(expressions.length > 0 && expressions.length <= 2) ? process.env.NODE_ENV !== "production" ? invariant(false, 'the "-" operator expects exactly 2 operands') : invariant(false) : void 0;
if (expressions.length === 1) {
return checkSimpleExpression(expressions[0], version);
} else {
var startVersion = expressions[0],
endVersion = expressions[1];
!(isSimpleVersion(startVersion) && isSimpleVersion(endVersion)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'operands to the "-" operator must be simple (no modifiers)') : invariant(false) : void 0;
return checkSimpleExpression('>=' + startVersion, version) && checkSimpleExpression('<=' + endVersion, version);
}
}
/**
* Checks if `range` matches `version`. `range` should be a "simple" range (ie.
* not a compound range using the " - " or "||" operators).
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
function checkSimpleExpression(range, version) {
range = range.trim();
if (range === '') {
return true;
}
var versionComponents = version.split(componentRegex);
var _getModifierAndCompon = getModifierAndComponents(range),
modifier = _getModifierAndCompon.modifier,
rangeComponents = _getModifierAndCompon.rangeComponents;
switch (modifier) {
case '<':
return checkLessThan(versionComponents, rangeComponents);
case '<=':
return checkLessThanOrEqual(versionComponents, rangeComponents);
case '>=':
return checkGreaterThanOrEqual(versionComponents, rangeComponents);
case '>':
return checkGreaterThan(versionComponents, rangeComponents);
case '~':
case '~>':
return checkApproximateVersion(versionComponents, rangeComponents);
default:
return checkEqual(versionComponents, rangeComponents);
}
}
/**
* Checks whether `a` is less than `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkLessThan(a, b) {
return compareComponents(a, b) === -1;
}
/**
* Checks whether `a` is less than or equal to `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkLessThanOrEqual(a, b) {
var result = compareComponents(a, b);
return result === -1 || result === 0;
}
/**
* Checks whether `a` is equal to `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkEqual(a, b) {
return compareComponents(a, b) === 0;
}
/**
* Checks whether `a` is greater than or equal to `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkGreaterThanOrEqual(a, b) {
var result = compareComponents(a, b);
return result === 1 || result === 0;
}
/**
* Checks whether `a` is greater than `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkGreaterThan(a, b) {
return compareComponents(a, b) === 1;
}
/**
* Checks whether `a` is "reasonably close" to `b` (as described in
* https://www.npmjs.org/doc/misc/semver.html). For example, if `b` is "1.3.1"
* then "reasonably close" is defined as ">= 1.3.1 and < 1.4".
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkApproximateVersion(a, b) {
var lowerBound = b.slice();
var upperBound = b.slice();
if (upperBound.length > 1) {
upperBound.pop();
}
var lastIndex = upperBound.length - 1;
var numeric = parseInt(upperBound[lastIndex], 10);
if (isNumber(numeric)) {
upperBound[lastIndex] = numeric + 1 + '';
}
return checkGreaterThanOrEqual(a, lowerBound) && checkLessThan(a, upperBound);
}
/**
* Extracts the optional modifier (<, <=, =, >=, >, ~, ~>) and version
* components from `range`.
*
* For example, given `range` ">= 1.2.3" returns an object with a `modifier` of
* `">="` and `components` of `[1, 2, 3]`.
*
* @param {string} range
* @returns {object}
*/
function getModifierAndComponents(range) {
var rangeComponents = range.split(componentRegex);
var matches = rangeComponents[0].match(modifierRegex);
!matches ? process.env.NODE_ENV !== "production" ? invariant(false, 'expected regex to match but it did not') : invariant(false) : void 0;
return {
modifier: matches[1],
rangeComponents: [matches[2]].concat(rangeComponents.slice(1))
};
}
/**
* Determines if `number` is a number.
*
* @param {mixed} number
* @returns {boolean}
*/
function isNumber(number) {
return !isNaN(number) && isFinite(number);
}
/**
* Tests whether `range` is a "simple" version number without any modifiers
* (">", "~" etc).
*
* @param {string} range
* @returns {boolean}
*/
function isSimpleVersion(range) {
return !getModifierAndComponents(range).modifier;
}
/**
* Zero-pads array `array` until it is at least `length` long.
*
* @param {array} array
* @param {number} length
*/
function zeroPad(array, length) {
for (var i = array.length; i < length; i++) {
array[i] = '0';
}
}
/**
* Normalizes `a` and `b` in preparation for comparison by doing the following:
*
* - zero-pads `a` and `b`
* - marks any "x", "X" or "*" component in `b` as equivalent by zero-ing it out
* in both `a` and `b`
* - marks any final "*" component in `b` as a greedy wildcard by zero-ing it
* and all of its successors in `a`
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {array<array<string>>}
*/
function normalizeVersions(a, b) {
a = a.slice();
b = b.slice();
zeroPad(a, b.length); // mark "x" and "*" components as equal
for (var i = 0; i < b.length; i++) {
var matches = b[i].match(/^[x*]$/i);
if (matches) {
b[i] = a[i] = '0'; // final "*" greedily zeros all remaining components
if (matches[0] === '*' && i === b.length - 1) {
for (var j = i; j < a.length; j++) {
a[j] = '0';
}
}
}
}
zeroPad(b, a.length);
return [a, b];
}
/**
* Returns the numerical -- not the lexicographical -- ordering of `a` and `b`.
*
* For example, `10-alpha` is greater than `2-beta`.
*
* @param {string} a
* @param {string} b
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
* or greater than `b`, respectively
*/
function compareNumeric(a, b) {
var aPrefix = a.match(numericRegex)[1];
var bPrefix = b.match(numericRegex)[1];
var aNumeric = parseInt(aPrefix, 10);
var bNumeric = parseInt(bPrefix, 10);
if (isNumber(aNumeric) && isNumber(bNumeric) && aNumeric !== bNumeric) {
return compare(aNumeric, bNumeric);
} else {
return compare(a, b);
}
}
/**
* Returns the ordering of `a` and `b`.
*
* @param {string|number} a
* @param {string|number} b
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
* or greater than `b`, respectively
*/
function compare(a, b) {
!(typeof a === typeof b) ? process.env.NODE_ENV !== "production" ? invariant(false, '"a" and "b" must be of the same type') : invariant(false) : void 0;
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
/**
* Compares arrays of version components.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
* or greater than `b`, respectively
*/
function compareComponents(a, b) {
var _normalizeVersions = normalizeVersions(a, b),
aNormalized = _normalizeVersions[0],
bNormalized = _normalizeVersions[1];
for (var i = 0; i < bNormalized.length; i++) {
var result = compareNumeric(aNormalized[i], bNormalized[i]);
if (result) {
return result;
}
}
return 0;
}
var VersionRange = {
/**
* Checks whether `version` satisfies the `range` specification.
*
* We support a subset of the expressions defined in
* https://www.npmjs.org/doc/misc/semver.html:
*
* version Must match version exactly
* =version Same as just version
* >version Must be greater than version
* >=version Must be greater than or equal to version
* <version Must be less than version
* <=version Must be less than or equal to version
* ~version Must be at least version, but less than the next significant
* revision above version:
* "~1.2.3" is equivalent to ">= 1.2.3 and < 1.3"
* ~>version Equivalent to ~version
* 1.2.x Must match "1.2.x", where "x" is a wildcard that matches
* anything
* 1.2.* Similar to "1.2.x", but "*" in the trailing position is a
* "greedy" wildcard, so will match any number of additional
* components:
* "1.2.*" will match "1.2.1", "1.2.1.1", "1.2.1.1.1" etc
* * Any version
* "" (Empty string) Same as *
* v1 - v2 Equivalent to ">= v1 and <= v2"
* r1 || r2 Passes if either r1 or r2 are satisfied
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
contains: function contains(range, version) {
return checkOrExpression(range.trim(), version.trim());
}
};
module.exports = VersionRange;

View File

@@ -0,0 +1,393 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule VersionRange
*/
'use strict';
const invariant = require("./invariant");
const componentRegex = /\./;
const orRegex = /\|\|/;
const rangeRegex = /\s+\-\s+/;
const modifierRegex = /^(<=|<|=|>=|~>|~|>|)?\s*(.+)/;
const numericRegex = /^(\d*)(.*)/;
/**
* Splits input `range` on "||" and returns true if any subrange matches
* `version`.
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
function checkOrExpression(range, version) {
const expressions = range.split(orRegex);
if (expressions.length > 1) {
return expressions.some(range => VersionRange.contains(range, version));
} else {
range = expressions[0].trim();
return checkRangeExpression(range, version);
}
}
/**
* Splits input `range` on " - " (the surrounding whitespace is required) and
* returns true if version falls between the two operands.
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
function checkRangeExpression(range, version) {
const expressions = range.split(rangeRegex);
invariant(expressions.length > 0 && expressions.length <= 2, 'the "-" operator expects exactly 2 operands');
if (expressions.length === 1) {
return checkSimpleExpression(expressions[0], version);
} else {
const [startVersion, endVersion] = expressions;
invariant(isSimpleVersion(startVersion) && isSimpleVersion(endVersion), 'operands to the "-" operator must be simple (no modifiers)');
return checkSimpleExpression('>=' + startVersion, version) && checkSimpleExpression('<=' + endVersion, version);
}
}
/**
* Checks if `range` matches `version`. `range` should be a "simple" range (ie.
* not a compound range using the " - " or "||" operators).
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
function checkSimpleExpression(range, version) {
range = range.trim();
if (range === '') {
return true;
}
const versionComponents = version.split(componentRegex);
const {
modifier,
rangeComponents
} = getModifierAndComponents(range);
switch (modifier) {
case '<':
return checkLessThan(versionComponents, rangeComponents);
case '<=':
return checkLessThanOrEqual(versionComponents, rangeComponents);
case '>=':
return checkGreaterThanOrEqual(versionComponents, rangeComponents);
case '>':
return checkGreaterThan(versionComponents, rangeComponents);
case '~':
case '~>':
return checkApproximateVersion(versionComponents, rangeComponents);
default:
return checkEqual(versionComponents, rangeComponents);
}
}
/**
* Checks whether `a` is less than `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkLessThan(a, b) {
return compareComponents(a, b) === -1;
}
/**
* Checks whether `a` is less than or equal to `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkLessThanOrEqual(a, b) {
const result = compareComponents(a, b);
return result === -1 || result === 0;
}
/**
* Checks whether `a` is equal to `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkEqual(a, b) {
return compareComponents(a, b) === 0;
}
/**
* Checks whether `a` is greater than or equal to `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkGreaterThanOrEqual(a, b) {
const result = compareComponents(a, b);
return result === 1 || result === 0;
}
/**
* Checks whether `a` is greater than `b`.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkGreaterThan(a, b) {
return compareComponents(a, b) === 1;
}
/**
* Checks whether `a` is "reasonably close" to `b` (as described in
* https://www.npmjs.org/doc/misc/semver.html). For example, if `b` is "1.3.1"
* then "reasonably close" is defined as ">= 1.3.1 and < 1.4".
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {boolean}
*/
function checkApproximateVersion(a, b) {
const lowerBound = b.slice();
const upperBound = b.slice();
if (upperBound.length > 1) {
upperBound.pop();
}
const lastIndex = upperBound.length - 1;
const numeric = parseInt(upperBound[lastIndex], 10);
if (isNumber(numeric)) {
upperBound[lastIndex] = numeric + 1 + '';
}
return checkGreaterThanOrEqual(a, lowerBound) && checkLessThan(a, upperBound);
}
/**
* Extracts the optional modifier (<, <=, =, >=, >, ~, ~>) and version
* components from `range`.
*
* For example, given `range` ">= 1.2.3" returns an object with a `modifier` of
* `">="` and `components` of `[1, 2, 3]`.
*
* @param {string} range
* @returns {object}
*/
function getModifierAndComponents(range) {
const rangeComponents = range.split(componentRegex);
const matches = rangeComponents[0].match(modifierRegex);
invariant(matches, 'expected regex to match but it did not');
return {
modifier: matches[1],
rangeComponents: [matches[2]].concat(rangeComponents.slice(1))
};
}
/**
* Determines if `number` is a number.
*
* @param {mixed} number
* @returns {boolean}
*/
function isNumber(number) {
return !isNaN(number) && isFinite(number);
}
/**
* Tests whether `range` is a "simple" version number without any modifiers
* (">", "~" etc).
*
* @param {string} range
* @returns {boolean}
*/
function isSimpleVersion(range) {
return !getModifierAndComponents(range).modifier;
}
/**
* Zero-pads array `array` until it is at least `length` long.
*
* @param {array} array
* @param {number} length
*/
function zeroPad(array, length) {
for (let i = array.length; i < length; i++) {
array[i] = '0';
}
}
/**
* Normalizes `a` and `b` in preparation for comparison by doing the following:
*
* - zero-pads `a` and `b`
* - marks any "x", "X" or "*" component in `b` as equivalent by zero-ing it out
* in both `a` and `b`
* - marks any final "*" component in `b` as a greedy wildcard by zero-ing it
* and all of its successors in `a`
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {array<array<string>>}
*/
function normalizeVersions(a, b) {
a = a.slice();
b = b.slice();
zeroPad(a, b.length); // mark "x" and "*" components as equal
for (let i = 0; i < b.length; i++) {
const matches = b[i].match(/^[x*]$/i);
if (matches) {
b[i] = a[i] = '0'; // final "*" greedily zeros all remaining components
if (matches[0] === '*' && i === b.length - 1) {
for (let j = i; j < a.length; j++) {
a[j] = '0';
}
}
}
}
zeroPad(b, a.length);
return [a, b];
}
/**
* Returns the numerical -- not the lexicographical -- ordering of `a` and `b`.
*
* For example, `10-alpha` is greater than `2-beta`.
*
* @param {string} a
* @param {string} b
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
* or greater than `b`, respectively
*/
function compareNumeric(a, b) {
const aPrefix = a.match(numericRegex)[1];
const bPrefix = b.match(numericRegex)[1];
const aNumeric = parseInt(aPrefix, 10);
const bNumeric = parseInt(bPrefix, 10);
if (isNumber(aNumeric) && isNumber(bNumeric) && aNumeric !== bNumeric) {
return compare(aNumeric, bNumeric);
} else {
return compare(a, b);
}
}
/**
* Returns the ordering of `a` and `b`.
*
* @param {string|number} a
* @param {string|number} b
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
* or greater than `b`, respectively
*/
function compare(a, b) {
invariant(typeof a === typeof b, '"a" and "b" must be of the same type');
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
}
/**
* Compares arrays of version components.
*
* @param {array<string>} a
* @param {array<string>} b
* @returns {number} -1, 0 or 1 to indicate whether `a` is less than, equal to,
* or greater than `b`, respectively
*/
function compareComponents(a, b) {
const [aNormalized, bNormalized] = normalizeVersions(a, b);
for (let i = 0; i < bNormalized.length; i++) {
const result = compareNumeric(aNormalized[i], bNormalized[i]);
if (result) {
return result;
}
}
return 0;
}
var VersionRange = {
/**
* Checks whether `version` satisfies the `range` specification.
*
* We support a subset of the expressions defined in
* https://www.npmjs.org/doc/misc/semver.html:
*
* version Must match version exactly
* =version Same as just version
* >version Must be greater than version
* >=version Must be greater than or equal to version
* <version Must be less than version
* <=version Must be less than or equal to version
* ~version Must be at least version, but less than the next significant
* revision above version:
* "~1.2.3" is equivalent to ">= 1.2.3 and < 1.3"
* ~>version Equivalent to ~version
* 1.2.x Must match "1.2.x", where "x" is a wildcard that matches
* anything
* 1.2.* Similar to "1.2.x", but "*" in the trailing position is a
* "greedy" wildcard, so will match any number of additional
* components:
* "1.2.*" will match "1.2.1", "1.2.1.1", "1.2.1.1.1" etc
* * Any version
* "" (Empty string) Same as *
* v1 - v2 Equivalent to ">= v1 and <= v2"
* r1 || r2 Passes if either r1 or r2 are satisfied
*
* @param {string} range
* @param {string} version
* @returns {boolean}
*/
contains(range, version) {
return checkOrExpression(range.trim(), version.trim());
}
};
module.exports = VersionRange;

View File

@@ -0,0 +1,16 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var ErrorUtils = jest.genMockFromModule("../ErrorUtils");
ErrorUtils.applyWithGuard.mockImplementation(function (callback, context, args) {
return callback.apply(context, args);
});
ErrorUtils.guard.mockImplementation(function (callback) {
return callback;
});
module.exports = ErrorUtils;

View File

@@ -0,0 +1,9 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
module.exports = require.requireActual("../base62");

View File

@@ -0,0 +1,9 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
module.exports = require.requireActual("../crc32");

View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/
'use strict';
var Deferred = require.requireActual("../Deferred");
var fetch = jest.fn(function (uri, options) {
var deferred = new Deferred();
fetch.mock.deferreds.push(deferred);
return deferred.getPromise();
});
fetch.mock.deferreds = [];
module.exports = fetch;

View File

@@ -0,0 +1,29 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/
'use strict';
var Deferred = require.requireActual("../Deferred");
function fetchWithRetries() {
var deferred = new Deferred();
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
fetchWithRetries.mock.calls.push(args);
fetchWithRetries.mock.deferreds.push(deferred);
return deferred.getPromise();
}
fetchWithRetries.mock = {
calls: [],
deferreds: []
};
module.exports = fetchWithRetries;

View File

@@ -0,0 +1,10 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
jest.unmock("../nullthrows");
module.exports = require("../nullthrows");

View File

@@ -0,0 +1,39 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @preventMunge
*
*/
/**
* Checks whether a collection name (e.g. "Map" or "Set") has a native polyfill
* that is safe to be used.
*/
function shouldPolyfillES6Collection(collectionName) {
var Collection = global[collectionName];
if (Collection == null) {
return true;
} // The iterator protocol depends on `Symbol.iterator`. If a collection is
// implemented, but `Symbol` is not, it's going to break iteration because
// we'll be using custom "@@iterator" instead, which is not implemented on
// native collections.
if (typeof global.Symbol !== 'function') {
return true;
}
var proto = Collection.prototype; // These checks are adapted from es6-shim: https://fburl.com/34437854
// NOTE: `isCallableWithoutNew` and `!supportsSubclassing` are not checked
// because they make debugging with "break on exceptions" difficult.
return Collection == null || typeof Collection !== 'function' || typeof proto.clear !== 'function' || new Collection().size !== 0 || typeof proto.keys !== 'function' || typeof proto.forEach !== 'function';
}
module.exports = shouldPolyfillES6Collection;

View File

@@ -0,0 +1,38 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule _shouldPolyfillES6Collection
* @preventMunge
* @flow
*/
/**
* Checks whether a collection name (e.g. "Map" or "Set") has a native polyfill
* that is safe to be used.
*/
function shouldPolyfillES6Collection(collectionName: string): boolean {
const Collection = global[collectionName];
if (Collection == null) {
return true;
} // The iterator protocol depends on `Symbol.iterator`. If a collection is
// implemented, but `Symbol` is not, it's going to break iteration because
// we'll be using custom "@@iterator" instead, which is not implemented on
// native collections.
if (typeof global.Symbol !== 'function') {
return true;
}
const proto = Collection.prototype; // These checks are adapted from es6-shim: https://fburl.com/34437854
// NOTE: `isCallableWithoutNew` and `!supportsSubclassing` are not checked
// because they make debugging with "break on exceptions" difficult.
return Collection == null || typeof Collection !== 'function' || typeof proto.clear !== 'function' || new Collection().size !== 0 || typeof proto.keys !== 'function' || typeof proto.forEach !== 'function';
}
module.exports = shouldPolyfillES6Collection;

View File

@@ -0,0 +1,123 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var aStackPool = [];
var bStackPool = [];
/**
* Checks if two values are equal. Values may be primitives, arrays, or objects.
* Returns true if both arguments have the same keys and values.
*
* @see http://underscorejs.org
* @copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
* @license MIT
*/
function areEqual(a, b) {
var aStack = aStackPool.length ? aStackPool.pop() : [];
var bStack = bStackPool.length ? bStackPool.pop() : [];
var result = eq(a, b, aStack, bStack);
aStack.length = 0;
bStack.length = 0;
aStackPool.push(aStack);
bStackPool.push(bStack);
return result;
}
function eq(a, b, aStack, bStack) {
if (a === b) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
return a !== 0 || 1 / a == 1 / b;
}
if (a == null || b == null) {
// a or b can be `null` or `undefined`
return false;
}
if (typeof a != 'object' || typeof b != 'object') {
return false;
}
var objToStr = Object.prototype.toString;
var className = objToStr.call(a);
if (className != objToStr.call(b)) {
return false;
}
switch (className) {
case '[object String]':
return a == String(b);
case '[object Number]':
return isNaN(a) || isNaN(b) ? false : a == Number(b);
case '[object Date]':
case '[object Boolean]':
return +a == +b;
case '[object RegExp]':
return a.source == b.source && a.global == b.global && a.multiline == b.multiline && a.ignoreCase == b.ignoreCase;
} // Assume equality for cyclic structures.
var length = aStack.length;
while (length--) {
if (aStack[length] == a) {
return bStack[length] == b;
}
}
aStack.push(a);
bStack.push(b);
var size = 0; // Recursively compare objects and arrays.
if (className === '[object Array]') {
size = a.length;
if (size !== b.length) {
return false;
} // Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!eq(a[size], b[size], aStack, bStack)) {
return false;
}
}
} else {
if (a.constructor !== b.constructor) {
return false;
}
if (a.hasOwnProperty('valueOf') && b.hasOwnProperty('valueOf')) {
return a.valueOf() == b.valueOf();
}
var keys = Object.keys(a);
if (keys.length != Object.keys(b).length) {
return false;
}
for (var i = 0; i < keys.length; i++) {
if (!eq(a[keys[i]], b[keys[i]], aStack, bStack)) {
return false;
}
}
}
aStack.pop();
bStack.pop();
return true;
}
module.exports = areEqual;

View File

@@ -0,0 +1,122 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule areEqual
* @flow
*/
const aStackPool = [];
const bStackPool = [];
/**
* Checks if two values are equal. Values may be primitives, arrays, or objects.
* Returns true if both arguments have the same keys and values.
*
* @see http://underscorejs.org
* @copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
* @license MIT
*/
function areEqual(a: any, b: any): boolean {
const aStack = aStackPool.length ? aStackPool.pop() : [];
const bStack = bStackPool.length ? bStackPool.pop() : [];
const result = eq(a, b, aStack, bStack);
aStack.length = 0;
bStack.length = 0;
aStackPool.push(aStack);
bStackPool.push(bStack);
return result;
}
function eq(a: any, b: any, aStack: Array<any>, bStack: Array<any>): boolean {
if (a === b) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
return a !== 0 || 1 / a == 1 / b;
}
if (a == null || b == null) {
// a or b can be `null` or `undefined`
return false;
}
if (typeof a != 'object' || typeof b != 'object') {
return false;
}
const objToStr = Object.prototype.toString;
const className = objToStr.call(a);
if (className != objToStr.call(b)) {
return false;
}
switch (className) {
case '[object String]':
return a == String(b);
case '[object Number]':
return isNaN(a) || isNaN(b) ? false : a == Number(b);
case '[object Date]':
case '[object Boolean]':
return +a == +b;
case '[object RegExp]':
return a.source == b.source && a.global == b.global && a.multiline == b.multiline && a.ignoreCase == b.ignoreCase;
} // Assume equality for cyclic structures.
let length = aStack.length;
while (length--) {
if (aStack[length] == a) {
return bStack[length] == b;
}
}
aStack.push(a);
bStack.push(b);
let size = 0; // Recursively compare objects and arrays.
if (className === '[object Array]') {
size = a.length;
if (size !== b.length) {
return false;
} // Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!eq(a[size], b[size], aStack, bStack)) {
return false;
}
}
} else {
if (a.constructor !== b.constructor) {
return false;
}
if (a.hasOwnProperty('valueOf') && b.hasOwnProperty('valueOf')) {
return a.valueOf() == b.valueOf();
}
const keys = Object.keys(a);
if (keys.length != Object.keys(b).length) {
return false;
}
for (let i = 0; i < keys.length; i++) {
if (!eq(a[keys[i]], b[keys[i]], aStack, bStack)) {
return false;
}
}
}
aStack.pop();
bStack.pop();
return true;
}
module.exports = areEqual;

View File

@@ -0,0 +1,28 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
'use strict';
var BASE62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
function base62(number) {
if (!number) {
return '0';
}
var string = '';
while (number > 0) {
string = BASE62[number % 62] + string;
number = Math.floor(number / 62);
}
return string;
}
module.exports = base62;

View File

@@ -0,0 +1,29 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule base62
* @flow
*/
'use strict';
const BASE62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
function base62(number: number): string {
if (!number) {
return '0';
}
let string = '';
while (number > 0) {
string = BASE62[number % 62] + string;
number = Math.floor(number / 62);
}
return string;
}
module.exports = base62;

View File

@@ -0,0 +1,28 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var _hyphenPattern = /-(.)/g;
/**
* Camelcases a hyphenated string, for example:
*
* > camelize('background-color')
* < "backgroundColor"
*
* @param {string} string
* @return {string}
*/
function camelize(string) {
return string.replace(_hyphenPattern, function (_, character) {
return character.toUpperCase();
});
}
module.exports = camelize;

View File

@@ -0,0 +1,27 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule camelize
* @typechecks
*/
const _hyphenPattern = /-(.)/g;
/**
* Camelcases a hyphenated string, for example:
*
* > camelize('background-color')
* < "backgroundColor"
*
* @param {string} string
* @return {string}
*/
function camelize(string) {
return string.replace(_hyphenPattern, function (_, character) {
return character.toUpperCase();
});
}
module.exports = camelize;

View File

@@ -0,0 +1,36 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
'use strict';
var camelize = require("./camelize");
var msPattern = /^-ms-/;
/**
* Camelcases a hyphenated CSS property name, for example:
*
* > camelizeStyleName('background-color')
* < "backgroundColor"
* > camelizeStyleName('-moz-transition')
* < "MozTransition"
* > camelizeStyleName('-ms-transition')
* < "msTransition"
*
* As Andi Smith suggests
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
* is converted to lowercase `ms`.
*
* @param {string} string
* @return {string}
*/
function camelizeStyleName(string) {
return camelize(string.replace(msPattern, 'ms-'));
}
module.exports = camelizeStyleName;

View File

@@ -0,0 +1,37 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule camelizeStyleName
* @typechecks
*/
'use strict';
const camelize = require("./camelize");
const msPattern = /^-ms-/;
/**
* Camelcases a hyphenated CSS property name, for example:
*
* > camelizeStyleName('background-color')
* < "backgroundColor"
* > camelizeStyleName('-moz-transition')
* < "MozTransition"
* > camelizeStyleName('-ms-transition')
* < "msTransition"
*
* As Andi Smith suggests
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
* is converted to lowercase `ms`.
*
* @param {string} string
* @return {string}
*/
function camelizeStyleName(string) {
return camelize(string.replace(msPattern, 'ms-'));
}
module.exports = camelizeStyleName;

View File

@@ -0,0 +1,16 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
/**
* Here is the native and polyfill version of cancelAnimationFrame.
* Please don't use it directly and use cancelAnimationFrame module instead.
*/
var cancelAnimationFrame = global.cancelAnimationFrame || global.webkitCancelAnimationFrame || global.mozCancelAnimationFrame || global.oCancelAnimationFrame || global.msCancelAnimationFrame || global.clearTimeout;
module.exports = cancelAnimationFrame;

View File

@@ -0,0 +1,15 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule cancelAnimationFramePolyfill
*/
/**
* Here is the native and polyfill version of cancelAnimationFrame.
* Please don't use it directly and use cancelAnimationFrame module instead.
*/
const cancelAnimationFrame = global.cancelAnimationFrame || global.webkitCancelAnimationFrame || global.mozCancelAnimationFrame || global.oCancelAnimationFrame || global.msCancelAnimationFrame || global.clearTimeout;
module.exports = cancelAnimationFrame;

28
smart-app-city/frontend/node_modules/fbjs/lib/clamp.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
* @typechecks
*/
/**
* Clamps (or clips or confines) the value to be between min and max.
*/
function clamp(value, min, max) {
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}
module.exports = clamp;

View File

@@ -0,0 +1,27 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule clamp
* @flow
* @typechecks
*/
/**
* Clamps (or clips or confines) the value to be between min and max.
*/
function clamp(value: number, min: number, max: number): number {
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}
module.exports = clamp;

View File

@@ -0,0 +1,28 @@
/**
* Copyright 2015-present Facebook. All Rights Reserved.
*
* @typechecks
*
*/
'use strict';
/**
* Returns a new Array containing all the element of the source array except
* `null` and `undefined` ones. This brings the benefit of strong typing over
* `Array.prototype.filter`.
*/
function compactArray(array) {
var result = [];
for (var i = 0; i < array.length; ++i) {
var elem = array[i];
if (elem != null) {
result.push(elem);
}
}
return result;
}
module.exports = compactArray;

View File

@@ -0,0 +1,29 @@
/**
* Copyright 2015-present Facebook. All Rights Reserved.
*
* @providesModule compactArray
* @typechecks
* @flow
*/
'use strict';
/**
* Returns a new Array containing all the element of the source array except
* `null` and `undefined` ones. This brings the benefit of strong typing over
* `Array.prototype.filter`.
*/
function compactArray<T>(array: Array<T | null | void>): Array<T> {
var result = [];
for (var i = 0; i < array.length; ++i) {
var elem = array[i];
if (elem != null) {
result.push(elem);
}
}
return result;
}
module.exports = compactArray;

View File

@@ -0,0 +1,35 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @typechecks
*/
var push = Array.prototype.push;
/**
* Concats an array of arrays into a single flat array.
*
* @param {array} array
* @return {array}
*/
function concatAllArray(array) {
var ret = [];
for (var ii = 0; ii < array.length; ii++) {
var value = array[ii];
if (Array.isArray(value)) {
push.apply(ret, value);
} else if (value != null) {
throw new TypeError('concatAllArray: All items in the array must be an array or null, ' + 'got "' + value + '" at index "' + ii + '" instead');
}
}
return ret;
}
module.exports = concatAllArray;

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule concatAllArray
* @typechecks
*/
var push = Array.prototype.push;
/**
* Concats an array of arrays into a single flat array.
*
* @param {array} array
* @return {array}
*/
function concatAllArray(array) {
var ret = [];
for (var ii = 0; ii < array.length; ii++) {
var value = array[ii];
if (Array.isArray(value)) {
push.apply(ret, value);
} else if (value != null) {
throw new TypeError('concatAllArray: All items in the array must be an array or null, ' + 'got "' + value + '" at index "' + ii + '" instead');
}
}
return ret;
}
module.exports = concatAllArray;

View File

@@ -0,0 +1,37 @@
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
var isTextNode = require("./isTextNode");
/*eslint-disable no-bitwise */
/**
* Checks if a given DOM node contains or is another DOM node.
*/
function containsNode(outerNode, innerNode) {
if (!outerNode || !innerNode) {
return false;
} else if (outerNode === innerNode) {
return true;
} else if (isTextNode(outerNode)) {
return false;
} else if (isTextNode(innerNode)) {
return containsNode(outerNode, innerNode.parentNode);
} else if ('contains' in outerNode) {
return outerNode.contains(innerNode);
} else if (outerNode.compareDocumentPosition) {
return !!(outerNode.compareDocumentPosition(innerNode) & 16);
} else {
return false;
}
}
module.exports = containsNode;

Some files were not shown because too many files have changed in this diff Show More