diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index c14d5c67b..000000000
--- a/.editorconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-end_of_line = lf
-insert_final_newline = true
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index 6170d8916..000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,20 +0,0 @@
-module.exports = {
- extends: 'airbnb',
- env: {
- node: true,
- mocha: true,
- browser: true,
- },
- rules: {
- 'no-param-reassign': 0,
- 'no-underscore-dangle': 0,
- 'consistent-return': 0,
- 'no-else-return': 0,
- 'max-len': 0,
- 'no-console': [ 2, { allow: ['warn', 'trace'] } ],
- 'no-restricted-syntax': [ 0, 'ForInStatement' ],
- 'no-new': 0,
- 'new-cap': 0,
- 'default-case': 0,
- }
-};
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index 92128ae10..000000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: CI
-on:
- push:
- branches: [master]
- pull_request:
- branches: [master]
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
- with:
- node-version: 16
- - run: npm ci
- - run: npm test
- env:
- SERVER_URL: https://qvnm6ag2.api.lncldglobal.com
- APPID: QvNM6AG2khJtBQo6WRMWqfLV-gzGzoHsz
- APPKEY: be2YmUduiuEnCB2VR9bLRnnV
- MASTERKEY: ${{ secrets.MASTER_KEY }}
- HOOKKEY: ${{ secrets.HOOK_KEY }}
- - uses: codecov/codecov-action@v3
- - run: npm run build
- - if: github.ref_name == 'master'
- run: |
- ./script/gh-release.sh
- ./script/gh-deploy.sh
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 469b916fe..000000000
--- a/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-node_modules/
-package/
-*tgz
-*.tar.gz
-coverage
-*.swp
-dist/js-sdk-api-docs
-npm-debug.log
-.nyc_output
-dist
-docs
diff --git a/.jsdocrc.json b/.jsdocrc.json
deleted file mode 100644
index 945ed1ff6..000000000
--- a/.jsdocrc.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "opts": {
- "template": "node_modules/docdash",
- "recurse": true
- }
-}
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index 839b35992..000000000
--- a/.npmignore
+++ /dev/null
@@ -1,20 +0,0 @@
-coverage
-demo
-docs
-node_modules
-src
-test
-webpack
-script
-recordings
-babel.config.json
-browserslist
-.gitignore
-.travis.yml
-gulpfile.babel.js
-readme.txt
-.nyc_output
-.editorconfig
-.eslintrc.js
-.jsdocrc.json
-.github
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c0001de14..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-language: node_js
-
-node_js:
- - '10'
-
-sudo: false
-install:
- - npm install -g codecov
- - npm install
-script:
- - npm test && codecov
- - npm run build
-after_success:
- - if [[ "$TRAVIS_BRANCH" == "master" ]] && [[ "${TRAVIS_PULL_REQUEST}" = "false" ]]; then
- ./script/release.sh;
- ./script/deploy.sh;
- fi
- - if [[ "$TRAVIS_BRANCH" == "next" ]] && [[ "${TRAVIS_PULL_REQUEST}" = "false" ]]; then
- ./script/release.sh next-dist;
- fi
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index c827ecdd9..000000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 LeanCloud
-
-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.
diff --git a/README.md b/README.md
deleted file mode 100644
index 230321ceb..000000000
--- a/README.md
+++ /dev/null
@@ -1,69 +0,0 @@
-# LeanCloud JavaScript SDK
-
-[](https://www.npmjs.com/package/leancloud-storage)
-
-[](https://travis-ci.org/leancloud/javascript-sdk)
-[](https://codecov.io/github/leancloud/javascript-sdk)
-[](https://snyk.io/test/github/leancloud/javascript-sdk)
-
-JavaScript SDK for [LeanCloud](http://leancloud.cn/).
-
-## 安装
-
-```
-// npm 安装
-npm install leancloud-storage --save
-// npm 安装 2.x 版本
-npm install leancloud-storage@2 --save
-```
-
-## 文档
-
-- [安装文档](https://leancloud.cn/docs/sdk_setup-js.html)
-- [使用文档](https://leancloud.cn/docs/leanstorage_guide-js.html)
-- [API 文档](https://leancloud.github.io/javascript-sdk/docs/)
-
-## 支持
-
-- 如果你发现了新的 bug,或者有新的 feature request,请新建一个 issue
-- 在使用过程中遇到了问题时
- - 如果你是商用版用户,请新建一个工单。
- - 也可以在 [论坛](https://forum.leancloud.cn/) 提问、讨论。
-
-## 贡献
-
-如果你希望为这个项目贡献代码,请按以下步骤进行:
-
-- `fork` 这个项目
-- `npm install` 安装相关依赖
-- 开发和调试
-- 确保测试全部通过 `npm run test`,浏览器环境打开 `test/test.html`
-- 提交并发起 `Pull Request`
-
-项目的目录结构说明如下:
-
-```
-├── dist // 编译之后生成的文件将会在此目录下
-│ ├── av.js // 浏览器版本
-│ ├── av-min.js
-│ ├── av-weapp.js // 小程序版本
-│ ├── av-weapp-min.js
-│ ├── node // 目录中为生成的 nodejs 版本代码
-│ └── ...
-├── src
-│ ├── index.js // node.js 环境入口文件
-│ └── ...
-└── test // 单元测试
-```
-
-## 发布流程
-
-1. 遵循 semver 提升版本号
- - src/version.js
- - package.json
-2. 对照 commit 历史写 changelog
-3. 提交当前所有改动
-4. 等待持续集成 pass
-5. 使用 GitHub 基于 dist 分支发布一个 release
-6. Fetch and checkout remote `dist` branch 并确认该提交的内容是即将发布的版本
-7. npm publish(`npm publish`,需 npm 协作者身份),如果是 pre-release 版本需要带 next tag
diff --git a/babel.config.json b/babel.config.json
deleted file mode 100644
index 9e25654dd..000000000
--- a/babel.config.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "presets": [
- [
- "@babel/preset-env",
- {
- "modules": "commonjs"
- }
- ]
- ],
- "plugins": [
- [
- "@babel/plugin-transform-runtime",
- {
- "corejs": 3
- }
- ],
- [
- "transform-inline-environment-variables",
- {
- "include": ["PLATFORM"]
- }
- ]
- ],
- "env": {
- "test": {
- "plugins": ["istanbul"]
- }
- }
-}
diff --git a/browserslist b/browserslist
deleted file mode 100644
index bd9fb7727..000000000
--- a/browserslist
+++ /dev/null
@@ -1,2 +0,0 @@
-> 0.25%
-not dead
\ No newline at end of file
diff --git a/changelog.md b/changelog.md
deleted file mode 100644
index bdf24134a..000000000
--- a/changelog.md
+++ /dev/null
@@ -1,1681 +0,0 @@
-## 4.15.3 (2024-07-04)
-
-### Bug Fixes
-
-- `resetPasswordBySmsCode` 和 `verifyMobilePhone` 支持传递 mobilePhoneNumber 参数。
-
-## 4.15.2 (2023-10-11)
-
-### Internal Changes
-
-升级依赖
-
-| package | from | to |
-| ---------------------------------- | ---------- | ---------- |
-| @leancloud/platform-adapters-weapp | 1.6.2 | 1.6.3 |
-| leancloud-realtime | 5.0.0-rc.7 | 5.0.0-rc.8 |
-
-## 4.15.1 (2023-09-25)
-
-### Bug Fixes
-
-- 修复在新版微信开发者工具中获取 AV.Object 时产生 warning 提示的问题。
-
-## 4.15.0 (2023-04-21)
-
-### Features
-
-- 国际节点支持通过 stream 构建文件(需要手动设置文件大小)
- ```js
- const stats = fs.statSync('my_file');
- const stream = fs.createReadStream('my_file');
- const file = new AV.File('my_file', stream);
- file.metaData('size', stats.size);
- file.save();
- ```
-
-## 4.14.0 (2022-12-15)
-
-### Features
-
-- 支持在 `AV.User.loginWithAuthData`, `AV.User.loginWithMiniApp`, `AV.User.loginWithAuthDataAndUnionId` 等函数的 `options` 中使用 `useMasterKey`, `sessionToken`, `user` 参数
-
-## 4.13.4(2022-10-31)
-
-### Bug Fixes
-
-- 修复 AV.Status 类型定义的错误。
-
-## 4.13.3(2022-10-31)
-
-### Bug Fixes
-
-- 修复 AV.Query#scan 当仅有一个 Object 满足条件约束时重复返回该 Object 的问题。
-- 补充 AV.Status 相关的类型定义。
-
-## 4.13.2(2022-08-23)
-
-### Bug Fixes
-
-- 修复异步 storage 平台上无法使用 AV.Friendship 的问题。
-
-## 4.13.1(2022-07-15)
-
-### Internal Changes
-
-升级依赖
-
-| package | from | to |
-| ------------------------------------ | ---------- | ---------- |
-| @leancloud/platform-adapters-browser | 1.5.2 | 1.5.3 |
-| @leancloud/platform-adapters-node | 1.5.2 | 1.5.3 |
-| @leancloud/platform-adapters-weapp | 1.6.1 | 1.6.2 |
-| leancloud-realtime | 5.0.0-rc.4 | 5.0.0-rc.7 |
-
-# 4.13.0(2022-07-12)
-
-### Features
-
-- 添加 `AV.File.censor` 和 `AV.File#censor` 方法用于发起文件审核请求(需要使用 masterKey)。
-
-### Internal Changes
-
-- 使用 babel@7 进行代码转义。
-- 使用 core-js@3 提供的 polyfills。
-
-## 4.12.3(2022-06-24)
-
-### Bug Fixes
-
-- 修复抛出的服务端异常不是 AV.Error 实例的问题。
-- 补充缺失的、修复错误的类型定义。
-
-## 4.12.2(2022-02-10)
-
-### Bug Fixes
-
-- 修复遍历 Class 时缺少最后一条数据的问题。
-- 修复 AV.Error 类型定义的错误。
-
-## 4.12.1(2022-02-09)
-
-### Bug Fixes
-
-- 修复某些情况下保存属性中包含 AV.File 的 AV.Object 时报错的问题。
-
-# 4.12.0(2021-09-16)
-
-### Features
-
-- `AV.Object.saveAll` 支持 `fetchWhenSave` 参数。
-- 添加 `AV.Query#findAndCount` 方法,用于同时获取查询结果和符合查询条件的总数。
-
-## 4.11.1(2021-06-09)
-
-### Bug Fixes
-
-- 修复了成功保存 `AV.File` 后没有设置文件的 `objectId` 和 `url` 属性的问题。
-- 修复了 `AV.File#save` 返回值可能不正确的问题。
-
-# 4.11.0(2021-06-09)
-
-### Features
-
-- 支持向国内节点保存大于 1GB 的文件。
-
-### Bug Fixes
-
-- 使用 `AV.init` 初始化 SDK 时,若未提供 `production` 参数,不再将目标环境重置为生产环境。
-
-## 4.10.1(2021-03-18)
-
-### Bug Fixes
-
-- 修复了文件保存失败时仍能获取到 URL 属性的问题。
-
-# 4.10.0(2021-01-19)
-
-### Features
-
-- 使用 masterKey 上传文件时,可自定义文件的 key :
- ```js
- const file = new AV.File(name, data);
- file.save({
- useMasterKey: true,
- key: 'custom-file-key',
- });
- ```
-
-### Internal Changes
-
-- 升级了 browser 、node 和 weapp 平台的 Adapters:
- package|from|to
- -|-|-
- @leancloud/adapter-types|`4.0.0`|`5.0.0`
- @leancloud/platform-adapters-browser|`1.4.0`|`1.5.2`
- @leancloud/platform-adapters-node|`1.4.0`|`1.5.2`
- @leancloud/platform-adapters-weapp|`1.5.0`|`1.6.1`
- 使用其他依赖 `@leancloud/adapter-types@5` 的 Adapters 也需要升级 `leancloud-storage` 到 4.10.0 。
-
-# 4.9.0(2020-12-18)
-
-### Bug Fixes
-
-- 修复了使用 `AV.Object.saveAll` 批量保存数据时,部分操作失败会影响后续操作执行的问题。
-
-### Internal Changes
-
-- 升级了内部依赖:
- package|from|to
- -|-|-
- @leancloud/adapter-types|`3.0.0`|`4.0.0`
- @leancloud/platform-adapters-browser|`1.1.0`|`1.4.0`
- @leancloud/platform-adapters-node|`1.1.0`|`1.4.0`
- @leancloud/platform-adapters-weapp|`1.2.0`|`1.5.0`
- leancloud-realtime|`5.0.0-rc.2`|`5.0.0-rc.4`
-
-## 4.8.3(2020-12-15)
-
-### Internal Changes
-
-- 修改了上传文件时 file key 的生成方式。
-
-## 4.8.2(2020-12-09)
-
-### Bug Fixes
-
-- 修复 `AV.SearchQuery#find` 未正确处理 `AuthOptions` 的问题。
-
-## 4.8.1(2020-12-03)
-
-### Bug Fixes
-
-- 修复构造 `AV.SearchQuery` 时省略 `className` 会抛出异常的问题。
-
-### Bug Fixes
-
-- 修复 `AV.SearchQuery#highlights` 不能正确处理数组参数的问题。
-
-# 4.8.0(2020-11-19)
-
-### Features
-
-- 添加 `AV.Friendship` 以支持好友所需的各项功能。
-- 添加 `AV.User#getFollowersAndFollowees` 方法用于查询指定用户的 followers 和 followees 。
-
-### Internal Changes
-
-- 现在保存通过 `AV.File.withURL` 方法创建的文件等同于直接在 \_File 中添加一行数据,不再自动生成 `mime_type`。
-
-# 4.7.0(2020-07-14)
-
-### Features
-
-- 增加下列方法以支持在修改手机号之前进行验证:
- - `AV.User.requestChangePhoneNumber`
- - `AV.User.changePhoneNumber`
-
-## 4.6.1 (2020-06-05)
-
-### Bug Fixes
-
-- 修复了在 Node.js 中运行时错误的提示不应使用 masterKey 并无法找到 `AV.Cloud.useMasterKey` 方法的问题。
-
-# 4.6.0 (2020-05-28)
-
-### Features
-
-- 增加了以下平台无关的小程序登录方法,通过各平台 Adapters 生成的 `authInfo` 进行登录:
- - `AV.User.loginWithMiniApp`
- - `AV.User#loginWithMiniApp`
-- 增加了 `AV.User.mergeUnionId` 方法用于合并 `authInfo` 与 `unionId`。
-
-### Bug Fixes
-
-- 修复了 React Native 上导入 SDK 抛异常的问题。详细的安装步骤参见 [《JavaScript SDK 安装指南 · React Native》](https://url.leanapp.cn/react-native-setup)。
-- 修复了通过 `AV.User.updatePassword` 更新密码后,未能同步更新当前用户的 `sessionToken` 的问题。
-- 修复了调用 `AV.User.become` 时,传递空 `sessionToken` 未抛异常的问题。
-
-## 4.5.3 (2020-04-03)
-
-### Bug Fixes
-
-- 修复了中国节点部分情况下文件上传失败但仍然返回了成功的问题。
-- 补充了平台无关版本的预编译文件:`av[-live-query]-core[-min].js`。
-
-## 4.5.2 (2020-03-27)
-
-### Bug Fixes
-
-- 修复了微信小程序中引入 SDK 抛异常 `Cannot read property 'core-js_shared' of undefined` 的问题。
-
-## 4.5.1 (2020-03-24)
-
-### Bug Fixes
-
-- 修复了不兼容 IE 11 等不支持 Promise 的运行环境的问题。
-- 修复了 TypeScript 找不到 `@leancloud/adapter-types` 模块的问题。
-
-### Internal Changes
-
-- `AV.Promise` 现在使用 `core-js` 的实现代替了 `es6-promise`。
-
-# 4.5.0 (2020-03-18)
-
-SDK [计划](https://github.com/leancloud/javascript-sdk/wiki/Roadmap) 在 5.0 中支持同时访问多个应用。在此之前,尽管当前版本中重复初始化 SDK 存在导致预期之外且难以追查的问题的风险,改变当前访问的应用的能力在很多场景下依然是有价值的。因此在这个版本中 SDK 允许通过多次调用 `init` 方法进行重新初始化。
-
-### Features
-
-- 多次调用 `init` 方法不再抛出「SDK 已初始化」的异常,而是会打印一条警告日志。
-
-# 4.4.0 (2020-03-17)
-
-这个版本中 SDK 新增了运行环境无关的版本,开发者可以在此基础上应用目标运行环境的 Adapters 来适配相应的运行平台。
-
-同时从这个版本开始 SDK 对各类平台的适配策略从之前的内置支持转为通过独立的第三方 Adapters 库支持。各个平台的 Adapters 将由 LeanCloud 与社区共同维护、独立演进、拥有独立的版本号。对于目前已经内置支持的平台,新版的 SDK 依然保留内置了对应的预编译版本,因此这些平台可以沿用之前的使用方式(React Native 除外,因为目前内置的适配实现使用的 API 已经被标记为「不赞成使用」)。
-
-### Features
-
-- 增加 `/core` 与 `/live-query-core` 入口,通过这种方式引入的 SDK 不包含运行环境相关的逻辑,需要配置 Adapters 后才能运行。
-- React Native 的适配现在通过独立的 Adapters 库(`@leancloud/platform-adapters-react-native`)支持,因此这个版本的 SDK 中去掉了内置的预编译的 React Native 版本。
-
- 0&&void 0!==arguments[0]?arguments[0]:O._getAVPath("subscriptionId"),e=O._subscriptionId=d();return O.localStorage.setItemAsync(t,e).then(function(){return e})},O._getSubscriptionId=function(){if(O._subscriptionId)return i.default.resolve(O._subscriptionId);var t=O._getAVPath("subscriptionId");return O.localStorage.getItemAsync(t).then(function(e){return O._subscriptionId=e,O._subscriptionId||(e=O._refreshSubscriptionId(t)),e})},O._parseDate=_,O._extend=function(t,e){var n=v(this,t,e);return n.extend=this.extend,n},O._encode=function(t,e,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];if(t instanceof O.Object){if(n)throw new Error("AV.Objects not allowed here");return e&&!l.include(e,t)&&t._hasData?t._toFullJSON((0,o.default)(e).call(e,t),r):t._toPointer()}if(t instanceof O.ACL)return t.toJSON();if(l.isDate(t))return r?{__type:"Date",iso:t.toJSON()}:t.toJSON();if(t instanceof O.GeoPoint)return t.toJSON();if(l.isArray(t))return(0,a.default)(l).call(l,t,function(t){return O._encode(t,e,n,r)});if(l.isRegExp(t))return t.source;if(t instanceof O.Relation)return t.toJSON();if(t instanceof O.Op)return t.toJSON();if(t instanceof O.File){if(!t.url()&&!t.id)throw new Error("Tried to save an object containing an unsaved file.");return t._toFullJSON(e,r)}return l.isObject(t)?l.mapObject(t,function(t,i){return O._encode(t,e,n,r)}):t},O._decode=function(t,e){if(!l.isObject(t)||l.isDate(t))return t;if(l.isArray(t))return(0,a.default)(l).call(l,t,function(t){return O._decode(t)});if(t instanceof O.Object)return t;if(t instanceof O.File)return t;if(t instanceof O.Op)return t;if(t instanceof O.GeoPoint)return t;if(t instanceof O.ACL)return t;if("ACL"===e)return new O.ACL(t);if(t.__op)return O.Op._decode(t);var n;if("Pointer"===t.__type){n=t.className;var r=O.Object._create(n);if((0,u.default)(t).length>3){var i=l.clone(t);delete i.__type,delete i.className,r._finishFetch(i,!0)}else r._finishFetch({objectId:t.objectId},!1);return r}if("Object"===t.__type){n=t.className;var o=l.clone(t);delete o.__type,delete o.className;var s=O.Object._create(n);return s._finishFetch(o,!0),s}if("Date"===t.__type)return O._parseDate(t.iso);if("GeoPoint"===t.__type)return new O.GeoPoint({latitude:t.latitude,longitude:t.longitude});if("Relation"===t.__type){if(!e)throw new Error("key missing decoding a Relation");var c=new O.Relation(null,e);return c.targetClassName=t.className,c}if("File"===t.__type){var f=new O.File(t.name),d=l.clone(t);return delete d.__type,f._finishFetch(d),f}return l.mapObject(t,O._decode)},O.parseJSON=O._decode,O.parse=function(t){return O.parseJSON(JSON.parse(t))},O.stringify=function(t){return(0,s.default)(O._encode(t,[],!1,!0))},O._encodeObjectOrArray=function(t){var e=function(t){return t&&t._toFullJSON&&(t=t._toFullJSON([])),l.mapObject(t,function(t){return O._encode(t,[])})};return l.isArray(t)?(0,a.default)(t).call(t,function(t){return e(t)}):e(t)},O._arrayEach=l.each,O._traverse=function(t,e,n){if(t instanceof O.Object){if(n=n||[],(0,c.default)(l).call(l,n,t)>=0)return;return n.push(t),O._traverse(t.attributes,e,n),e(t)}return t instanceof O.Relation||t instanceof O.File?e(t):l.isArray(t)?(l.each(t,function(r,i){var o=O._traverse(r,e,n);o&&(t[i]=o)}),e(t)):l.isObject(t)?(O._each(t,function(r,i){var o=O._traverse(r,e,n);o&&(t[i]=o)}),e(t)):e(t)},O._objectEach=O._each=function(t,e){l.isObject(t)?l.each((0,f.default)(l).call(l,t),function(n){e(t[n],n)}):l.each(t,e)},O.debug={enable:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"leancloud*";return h.enable(t)},disable:h.disable},O.setAdapters=m,t.exports=O}).call(e,n(105))},function(t,e,n){"use strict";function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function i(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function o(e){if(e[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+e[0]+(this.useColors?"%c ":" ")+"+"+t.exports.humanize(this.diff),this.useColors){var n="color: "+this.color;e.splice(1,0,n,"color: inherit");var r=0,i=0;e[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(r++,"%c"===t&&(i=r))}),e.splice(i,0,n)}}function a(){var t;return"object"===("undefined"==typeof console?"undefined":r(console))&&console.log&&(t=console).log.apply(t,arguments)}function u(t){try{t?e.storage.setItem("debug",t):e.storage.removeItem("debug")}catch(t){}}function s(){var t;try{t=e.storage.getItem("debug")}catch(t){}return!t&&"undefined"!=typeof process&&"env"in process&&(t=process.env.DEBUG),t}e.log=a,e.formatArgs=o,e.save=u,e.load=s,e.useColors=i,e.storage=function(){try{return localStorage}catch(t){}}(),e.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.exports=n(375)(e),t.exports.formatters.j=function(t){try{return JSON.stringify(t)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}}},function(t,e,n){"use strict";var r=n(2),i=r(n(48)),o=n(1),a=n(218),u=n(28),s=u.inherits,c=s(a,{constructor:function(){a.apply(this),this._adapters={}},getAdapter:function(t){var e=this._adapters[t];if(void 0===e)throw new Error("".concat(t," adapter is not configured"));return e},setAdapters:function(t){var e=this;o.extend(this._adapters,t),(0,i.default)(o).call(o,t).forEach(function(n){return e.emit(n,t[n])})}}),f=new c;t.exports={getAdapter:f.getAdapter.bind(f),setAdapters:f.setAdapters.bind(f),adapterManager:f}},function(t,e,n){var r=n(63),i=Function.prototype,o=i.apply,a=i.call;t.exports="object"==typeof Reflect&&Reflect.apply||(r?a.bind(o):function(){return a.apply(o,arguments)})},function(t,e,n){var r=n(4);t.exports=!r(function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})},function(t,e,n){var r=n(19),i=n(11),o=n(138),a=n(41),u=n(33),s=n(82),c=n(14),f=n(141),l=Object.getOwnPropertyDescriptor;e.f=r?l:function(t,e){if(t=u(t),e=s(e),f)try{return l(t,e)}catch(t){}if(c(t,e))return a(!i(o.f,t,e),t[e])}},function(t,e,n){var r=n(6),i=r({}.toString),o=r("".slice);t.exports=function(t){return o(i(t),8,-1)}},function(t,e){var n=String;t.exports=function(t){try{return n(t)}catch(t){return"Object"}}},function(t,e,n){var r=n(31),i=n(108);(t.exports=function(t,e){return i[t]||(i[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.23.3",mode:r?"pure":"global",copyright:"© 2014-2022 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.23.3/LICENSE",source:"https://github.com/zloirock/core-js"})},function(t,e,n){var r=n(50),i=n(11),o=n(21),a=n(66),u=n(149),s=n(42),c=n(20),f=n(150),l=n(90),d=n(151),h=TypeError,p=function(t,e){this.stopped=t,this.result=e},v=p.prototype;t.exports=function(t,e,n){var _,b,g,m,y,O,w,j=n&&n.that,A=!(!n||!n.AS_ENTRIES),x=!(!n||!n.IS_ITERATOR),S=!(!n||!n.INTERRUPTED),E=r(e,j),C=function(t){return _&&d(_,"normal",t),new p(!0,t)},T=function(t){return A?(o(t),S?E(t[0],t[1],C):E(t[0],t[1])):S?E(t,C):E(t)};if(x)_=t;else{if(!(b=l(t)))throw h(a(t)+" is not iterable");if(u(b)){for(g=0,m=s(t);m>g;g++)if((y=T(t[g]))&&c(v,y))return y;return new p(!1)}_=f(t,b)}for(O=_.next;!(w=i(O,_)).done;){try{y=T(w.value)}catch(t){d(_,"throw",t)}if("object"==typeof y&&y&&c(v,y))return y}return new p(!1)}},function(t,e,n){var r=n(53),i=String;t.exports=function(t){if("Symbol"===r(t))throw TypeError("Cannot convert a Symbol value to a string");return i(t)}},function(t,e,n){"use strict";var r=n(33),i=n(152),o=n(52),a=n(91),u=n(32).f,s=n(153),c=n(31),f=n(19),l=a.set,d=a.getterFor("Array Iterator");t.exports=s(Array,"Array",function(t,e){l(this,{type:"Array Iterator",target:r(t),index:0,kind:e})},function(){var t=d(this),e=t.target,n=t.kind,r=t.index++;return!e||r>=e.length?(t.target=void 0,{value:void 0,done:!0}):"keys"==n?{value:r,done:!1}:"values"==n?{value:e[r],done:!1}:{value:[r,e[r]],done:!1}},"values");var h=o.Arguments=o.Array;if(i("keys"),i("values"),i("entries"),!c&&f&&"values"!==h.name)try{u(h,"name",{value:"values"})}catch(t){}},function(t,e){t.exports=function(t){try{return{error:!1,value:t()}}catch(t){return{error:!0,value:t}}}},function(t,e,n){var r=n(9),i=n(55),o=n(7),a=n(142),u=n(118),s=n(8),c=n(268),f=n(31),l=n(84),d=i&&i.prototype,h=s("species"),p=!1,v=o(r.PromiseRejectionEvent),_=a("Promise",function(){var t=u(i),e=t!==String(i);if(!e&&66===l)return!0;if(f&&(!d.catch||!d.finally))return!0;if(l>=51&&/native code/.test(t))return!1;var n=new i(function(t){t(1)}),r=function(t){t(function(){},function(){})},o=n.constructor={};return o[h]=r,!(p=n.then(function(){})instanceof r)||!e&&c&&!v});t.exports={CONSTRUCTOR:_,REJECTION_EVENT:v,SUBCLASSING:p}},function(t,e,n){n(70);var r=n(278),i=n(9),o=n(53),a=n(36),u=n(52),s=n(8),c=s("toStringTag");for(var f in r){var l=i[f],d=l&&l.prototype;d&&o(d)!==c&&a(d,c,f),u[f]=u.Array}},function(t,e,n){"use strict";n.d(e,"a",function(){return o}),n.d(e,"b",function(){return a});var r=n(3),i=n(285),o=r.s&&Object(i.a)(new DataView(new ArrayBuffer(8))),a="undefined"!=typeof Map&&Object(i.a)(new Map)},function(t,e,n){"use strict";function r(t){if(!Object(i.a)(t))return[];var e=[];for(var n in t)e.push(n);return o.h&&Object(a.a)(t,e),e}e.a=r;var i=n(45),o=n(3),a=n(172)},function(t,e,n){"use strict";function r(t){return i.a.toPath(t)}e.a=r;var i=n(23);n(181)},function(t,e,n){"use strict";function r(t,e,n){if(void 0===e)return t;switch(null==n?3:n){case 1:return function(n){return t.call(e,n)};case 3:return function(n,r,i){return t.call(e,n,r,i)};case 4:return function(n,r,i,o){return t.call(e,n,r,i,o)}}return function(){return t.apply(e,arguments)}}e.a=r},function(t,e,n){"use strict";function r(t,e,n){var r=[];return e=Object(i.a)(e,n),Object(o.a)(t,function(t,n,i){e(t,n,i)&&r.push(t)}),r}e.a=r;var i=n(18),o=n(47)},function(t,e,n){"use strict";function r(t,e,n,r){return Object(i.a)(t)||(t=Object(o.a)(t)),("number"!=typeof n||r)&&(n=0),Object(a.a)(t,e,n)>=0}e.a=r;var i=n(24),o=n(56),a=n(197)},function(t,e,n){var r=n(65);t.exports=Array.isArray||function(t){return"Array"==r(t)}},function(t,e,n){t.exports=n(222)},function(t,e,n){var r=n(242),i=n(83);t.exports=function(t){var e=r(t,"string");return i(e)?e:e+""}},function(t,e,n){var r=n(16),i=n(7),o=n(20),a=n(140),u=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=r("Symbol");return i(e)&&o(e.prototype,u(t))}},function(t,e,n){var r,i,o=n(9),a=n(85),u=o.process,s=o.Deno,c=u&&u.versions||s&&s.version,f=c&&c.v8;f&&(r=f.split("."),i=r[0]>0&&r[0]<4?1:+(r[0]+r[1])),!i&&a&&(!(r=a.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=a.match(/Chrome\/(\d+)/))&&(i=+r[1]),t.exports=i},function(t,e,n){var r=n(16);t.exports=r("navigator","userAgent")||""},function(t,e,n){var r=n(14),i=n(7),o=n(35),a=n(87),u=n(144),s=a("IE_PROTO"),c=Object,f=c.prototype;t.exports=u?c.getPrototypeOf:function(t){var e=o(t);if(r(e,s))return e[s];var n=e.constructor;return i(n)&&e instanceof n?n.prototype:e instanceof c?f:null}},function(t,e,n){var r=n(67),i=n(109),o=r("keys");t.exports=function(t){return o[t]||(o[t]=i(t))}},function(t,e,n){var r=n(6),i=n(21),o=n(245);t.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var t,e=!1,n={};try{t=r(Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set),t(n,[]),e=n instanceof Array}catch(t){}return function(n,r){return i(n),o(r),e?t(n,r):n.__proto__=r,n}}():void 0)},function(t,e){t.exports={}},function(t,e,n){var r=n(53),i=n(107),o=n(52),a=n(8),u=a("iterator");t.exports=function(t){if(void 0!=t)return i(t,u)||i(t,"@@iterator")||o[r(t)]}},function(t,e,n){var r,i,o,a=n(254),u=n(9),s=n(6),c=n(17),f=n(36),l=n(14),d=n(108),h=n(87),p=n(89),v=u.TypeError,_=u.WeakMap,b=function(t){return o(t)?i(t):r(t,{})},g=function(t){return function(e){var n;if(!c(e)||(n=i(e)).type!==t)throw v("Incompatible receiver, "+t+" required");return n}};if(a||d.state){var m=d.state||(d.state=new _),y=s(m.get),O=s(m.has),w=s(m.set);r=function(t,e){if(O(m,t))throw new v("Object already initialized");return e.facade=t,w(m,t,e),e},i=function(t){return y(m,t)||{}},o=function(t){return O(m,t)}}else{var j=h("state");p[j]=!0,r=function(t,e){if(l(t,j))throw new v("Object already initialized");return e.facade=t,f(t,j,e),e},i=function(t){return l(t,j)?t[j]:{}},o=function(t){return l(t,j)}}t.exports={set:r,get:i,has:o,enforce:b,getterFor:g}},function(t,e){},function(t,e,n){var r=n(6),i=n(4),o=n(7),a=n(53),u=n(16),s=n(118),c=function(){},f=[],l=u("Reflect","construct"),d=/^\s*(?:class|function)\b/,h=r(d.exec),p=!d.exec(c),v=function(t){if(!o(t))return!1;try{return l(c,f,t),!0}catch(t){return!1}},_=function(t){if(!o(t))return!1;switch(a(t)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return p||!!h(d,s(t))}catch(t){return!0}};_.sham=!0,t.exports=!l||i(function(){var t;return v(v.call)||!v(Object)||!v(function(){t=!0})||t})?_:v},function(t,e,n){var r=n(6);t.exports=r([].slice)},function(t,e,n){"use strict";var r=n(277).charAt,i=n(69),o=n(91),a=n(153),u=o.set,s=o.getterFor("String Iterator");a(String,"String",function(t){u(this,{type:"String Iterator",string:i(t),index:0})},function(){var t,e=s(this),n=e.string,i=e.index;return i>=n.length?{value:void 0,done:!0}:(t=r(n,i),e.index+=t.length,{value:t,done:!1})})},function(t,e,n){"use strict";function r(t){return t=Object(i.a)({},t),function(e){return Object(o.a)(e,t)}}e.a=r;var i=n(127),o=n(173)},function(t,e,n){"use strict";var r=n(22),i=n(189),o=n(23),a=Object(r.a)(function(t,e){var n=a.placeholder,r=function(){for(var o=0,a=e.length,u=Array(a),s=0;s=51||!r(function(){var e=[],n=e.constructor={};return n[a]=function(){return{foo:1}},1!==e[t](Boolean).foo})}},function(t,e,n){var r=n(50),i=n(6),o=n(139),a=n(35),u=n(42),s=n(211),c=i([].push),f=function(t){var e=1==t,n=2==t,i=3==t,f=4==t,l=6==t,d=7==t,h=5==t||l;return function(p,v,_,b){for(var g,m,y=a(p),O=o(y),w=r(v,_),j=u(O),A=0,x=b||s,S=e?x(p,j):n||d?x(p,0):void 0;j>A;A++)if((h||A in O)&&(g=O[A],m=w(g,A,y),t))if(e)S[A]=m;else if(m)switch(t){case 3:return!0;case 5:return g;case 6:return A;case 2:c(S,g)}else switch(t){case 4:return!1;case 7:c(S,g)}return l?-1:i||f?f:S}};t.exports={forEach:f(0),map:f(1),filter:f(2),some:f(3),every:f(4),find:f(5),findIndex:f(6),filterReject:f(7)}},function(t,e,n){t.exports=n(365)},function(t,e,n){"use strict";var r=n(2),i=r(n(135)),o=r(n(430)),a=r(n(39)),u=r(n(212)),s=r(n(34)),c=r(n(29)),f=(n(1),n(435)),l=f.timeout,d=n(60),h=d("leancloud:request"),p=d("leancloud:request:error"),v=n(61),_=v.getAdapter,b=0,g=function(t){var e=t.method,n=t.url,r=t.query,f=t.data,v=t.headers,g=void 0===v?{}:v,m=t.timeout,y=t.onprogress;if(r){var O,w,j,A=(0,o.default)(O=(0,a.default)(w=(0,u.default)(r)).call(w,function(t){var e,n=r[t];if(void 0!==n){var o="object"===(0,i.default)(n)?(0,s.default)(n):n;return(0,c.default)(e="".concat(encodeURIComponent(t),"=")).call(e,encodeURIComponent(o))}})).call(O,function(t){return t}).join("&");n=(0,c.default)(j="".concat(n,"?")).call(j,A)}var x=b++;h("request(%d) %s %s %o %o %o",x,e,n,r,f,g);var S=_("request"),E=S(n,{method:e,headers:g,data:f,onprogress:y}).then(function(t){if(h("response(%d) %d %O %o",x,t.status,t.data||t.text,t.header),!1===t.ok){var e=new Error;throw e.response=t,e}return t.data}).catch(function(t){throw t.response&&(d.enabled("leancloud:request")||p("request(%d) %s %s %o %o %o",x,e,n,r,f,g),p("response(%d) %d %O %o",x,t.response.status,t.response.data||t.response.text,t.response.header),t.statusCode=t.response.status,t.responseText=t.response.text,t.response=t.response.data),t});return m?l(E,m):E};t.exports=g},function(t,e,n){t.exports=n(440)},function(t,e){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e){var n=TypeError;t.exports=function(t){if(void 0==t)throw n("Can't call method on "+t);return t}},function(t,e,n){var r=n(30);t.exports=function(t,e){var n=t[e];return null==n?void 0:r(n)}},function(t,e,n){var r=n(9),i=n(244),o=r["__core-js_shared__"]||i("__core-js_shared__",{});t.exports=o},function(t,e,n){var r=n(6),i=0,o=Math.random(),a=r(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++i+o,36)}},function(t,e,n){var r=n(9),i=n(17),o=r.document,a=i(o)&&i(o.createElement);t.exports=function(t){return a?o.createElement(t):{}}},function(t,e,n){var r=n(145),i=n(114),o=i.concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return r(t,o)}},function(t,e,n){var r=n(113),i=Math.max,o=Math.min;t.exports=function(t,e){var n=r(t);return n<0?i(n+e,0):o(n,e)}},function(t,e,n){var r=n(248);t.exports=function(t){var e=+t;return e!==e||0===e?0:r(e)}},function(t,e){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},function(t,e){e.f=Object.getOwnPropertySymbols},function(t,e,n){var r=n(145),i=n(114);t.exports=Object.keys||function(t){return r(t,i)}},function(t,e,n){var r=n(8),i=r("toStringTag"),o={};o[i]="z",t.exports="[object z]"===String(o)},function(t,e,n){var r=n(6),i=n(7),o=n(108),a=r(Function.toString);i(o.inspectSource)||(o.inspectSource=function(t){return a(t)}),t.exports=o.inspectSource},function(t,e,n){var r=n(65),i=n(9);t.exports="process"==r(i.process)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3);n.d(e,"VERSION",function(){return r.e});var i=n(22);n.d(e,"restArguments",function(){return i.a});var o=n(45);n.d(e,"isObject",function(){return o.a});var a=n(280);n.d(e,"isNull",function(){return a.a});var u=n(162);n.d(e,"isUndefined",function(){return u.a});var s=n(163);n.d(e,"isBoolean",function(){return s.a});var c=n(281);n.d(e,"isElement",function(){return c.a});var f=n(121);n.d(e,"isString",function(){return f.a});var l=n(164);n.d(e,"isNumber",function(){return l.a});var d=n(282);n.d(e,"isDate",function(){return d.a});var h=n(283);n.d(e,"isRegExp",function(){return h.a});var p=n(284);n.d(e,"isError",function(){return p.a});var v=n(165);n.d(e,"isSymbol",function(){return v.a});var _=n(166);n.d(e,"isArrayBuffer",function(){return _.a});var b=n(122);n.d(e,"isDataView",function(){return b.a});var g=n(46);n.d(e,"isArray",function(){return g.a});var m=n(26);n.d(e,"isFunction",function(){return m.a});var y=n(123);n.d(e,"isArguments",function(){return y.a});var O=n(286);n.d(e,"isFinite",function(){return O.a});var w=n(167);n.d(e,"isNaN",function(){return w.a});var j=n(168);n.d(e,"isTypedArray",function(){return j.a});var A=n(288);n.d(e,"isEmpty",function(){return A.a});var x=n(173);n.d(e,"isMatch",function(){return x.a});var S=n(289);n.d(e,"isEqual",function(){return S.a});var E=n(291);n.d(e,"isMap",function(){return E.a});var C=n(292);n.d(e,"isWeakMap",function(){return C.a});var T=n(293);n.d(e,"isSet",function(){return T.a});var N=n(294);n.d(e,"isWeakSet",function(){return N.a});var I=n(12);n.d(e,"keys",function(){return I.a});var U=n(75);n.d(e,"allKeys",function(){return U.a});var P=n(56);n.d(e,"values",function(){return P.a});var k=n(295);n.d(e,"pairs",function(){return k.a});var R=n(174);n.d(e,"invert",function(){return R.a});var D=n(175);n.d(e,"functions",function(){return D.a}),n.d(e,"methods",function(){return D.a});var M=n(176);n.d(e,"extend",function(){return M.a});var L=n(127);n.d(e,"extendOwn",function(){return L.a}),n.d(e,"assign",function(){return L.a});var F=n(177);n.d(e,"defaults",function(){return F.a});var q=n(296);n.d(e,"create",function(){return q.a});var W=n(179);n.d(e,"clone",function(){return W.a});var B=n(297);n.d(e,"tap",function(){return B.a});var V=n(180);n.d(e,"get",function(){return V.a});var Q=n(298);n.d(e,"has",function(){return Q.a});var K=n(299);n.d(e,"mapObject",function(){return K.a});var z=n(129);n.d(e,"identity",function(){return z.a});var J=n(169);n.d(e,"constant",function(){return J.a});var G=n(184);n.d(e,"noop",function(){return G.a});var H=n(181);n.d(e,"toPath",function(){return H.a});var $=n(130);n.d(e,"property",function(){return $.a});var Y=n(300);n.d(e,"propertyOf",function(){return Y.a});var X=n(96);n.d(e,"matcher",function(){return X.a}),n.d(e,"matches",function(){return X.a});var Z=n(301);n.d(e,"times",function(){return Z.a});var tt=n(185);n.d(e,"random",function(){return tt.a});var et=n(131);n.d(e,"now",function(){return et.a});var nt=n(302);n.d(e,"escape",function(){return nt.a});var rt=n(303);n.d(e,"unescape",function(){return rt.a});var it=n(188);n.d(e,"templateSettings",function(){return it.a});var ot=n(305);n.d(e,"template",function(){return ot.a});var at=n(306);n.d(e,"result",function(){return at.a});var ut=n(307);n.d(e,"uniqueId",function(){return ut.a});var st=n(308);n.d(e,"chain",function(){return st.a});var ct=n(183);n.d(e,"iteratee",function(){return ct.a});var ft=n(97);n.d(e,"partial",function(){return ft.a});var lt=n(190);n.d(e,"bind",function(){return lt.a});var dt=n(309);n.d(e,"bindAll",function(){return dt.a});var ht=n(310);n.d(e,"memoize",function(){return ht.a});var pt=n(191);n.d(e,"delay",function(){return pt.a});var vt=n(311);n.d(e,"defer",function(){return vt.a});var _t=n(312);n.d(e,"throttle",function(){return _t.a});var bt=n(313);n.d(e,"debounce",function(){return bt.a});var gt=n(314);n.d(e,"wrap",function(){return gt.a});var mt=n(132);n.d(e,"negate",function(){return mt.a});var yt=n(315);n.d(e,"compose",function(){return yt.a});var Ot=n(316);n.d(e,"after",function(){return Ot.a});var wt=n(192);n.d(e,"before",function(){return wt.a});var jt=n(317);n.d(e,"once",function(){return jt.a});var At=n(193);n.d(e,"findKey",function(){return At.a});var xt=n(133);n.d(e,"findIndex",function(){return xt.a});var St=n(195);n.d(e,"findLastIndex",function(){return St.a});var Et=n(196);n.d(e,"sortedIndex",function(){return Et.a});var Ct=n(197);n.d(e,"indexOf",function(){return Ct.a});var Tt=n(318);n.d(e,"lastIndexOf",function(){return Tt.a});var Nt=n(199);n.d(e,"find",function(){return Nt.a}),n.d(e,"detect",function(){return Nt.a});var It=n(319);n.d(e,"findWhere",function(){return It.a});var Ut=n(47);n.d(e,"each",function(){return Ut.a}),n.d(e,"forEach",function(){return Ut.a});var Pt=n(58);n.d(e,"map",function(){return Pt.a}),n.d(e,"collect",function(){return Pt.a});var kt=n(320);n.d(e,"reduce",function(){return kt.a}),n.d(e,"foldl",function(){return kt.a}),n.d(e,"inject",function(){return kt.a});var Rt=n(321);n.d(e,"reduceRight",function(){return Rt.a}),n.d(e,"foldr",function(){return Rt.a});var Dt=n(78);n.d(e,"filter",function(){return Dt.a}),n.d(e,"select",function(){return Dt.a});var Mt=n(322);n.d(e,"reject",function(){return Mt.a});var Lt=n(323);n.d(e,"every",function(){return Lt.a}),n.d(e,"all",function(){return Lt.a});var Ft=n(324);n.d(e,"some",function(){return Ft.a}),n.d(e,"any",function(){return Ft.a});var qt=n(79);n.d(e,"contains",function(){return qt.a}),n.d(e,"includes",function(){return qt.a}),n.d(e,"include",function(){return qt.a});var Wt=n(325);n.d(e,"invoke",function(){return Wt.a});var Bt=n(134);n.d(e,"pluck",function(){return Bt.a});var Vt=n(326);n.d(e,"where",function(){return Vt.a});var Qt=n(201);n.d(e,"max",function(){return Qt.a});var Kt=n(327);n.d(e,"min",function(){return Kt.a});var zt=n(328);n.d(e,"shuffle",function(){return zt.a});var Jt=n(202);n.d(e,"sample",function(){return Jt.a});var Gt=n(329);n.d(e,"sortBy",function(){return Gt.a});var Ht=n(330);n.d(e,"groupBy",function(){return Ht.a});var $t=n(331);n.d(e,"indexBy",function(){return $t.a});var Yt=n(332);n.d(e,"countBy",function(){return Yt.a});var Xt=n(333);n.d(e,"partition",function(){return Xt.a});var Zt=n(334);n.d(e,"toArray",function(){return Zt.a});var te=n(335);n.d(e,"size",function(){return te.a});var ee=n(203);n.d(e,"pick",function(){return ee.a});var ne=n(337);n.d(e,"omit",function(){return ne.a});var re=n(338);n.d(e,"first",function(){return re.a}),n.d(e,"head",function(){return re.a}),n.d(e,"take",function(){return re.a});var ie=n(204);n.d(e,"initial",function(){return ie.a});var oe=n(339);n.d(e,"last",function(){return oe.a});var ae=n(205);n.d(e,"rest",function(){return ae.a}),n.d(e,"tail",function(){return ae.a}),n.d(e,"drop",function(){return ae.a});var ue=n(340);n.d(e,"compact",function(){return ue.a});var se=n(341);n.d(e,"flatten",function(){return se.a});var ce=n(342);n.d(e,"without",function(){return ce.a});var fe=n(207);n.d(e,"uniq",function(){return fe.a}),n.d(e,"unique",function(){return fe.a});var le=n(343);n.d(e,"union",function(){return le.a});var de=n(344);n.d(e,"intersection",function(){return de.a});var he=n(206);n.d(e,"difference",function(){return he.a});var pe=n(208);n.d(e,"unzip",function(){return pe.a}),n.d(e,"transpose",function(){return pe.a});var ve=n(345);n.d(e,"zip",function(){return ve.a});var _e=n(346);n.d(e,"object",function(){return _e.a});var be=n(347);n.d(e,"range",function(){return be.a});var ge=n(348);n.d(e,"chunk",function(){return ge.a});var me=n(349);n.d(e,"mixin",function(){return me.a});var ye=n(350);n.d(e,"default",function(){return ye.a})},function(t,e,n){"use strict";var r=n(15);e.a=Object(r.a)("String")},function(t,e,n){"use strict";function r(t){return null!=t&&Object(o.a)(t.getInt8)&&Object(a.a)(t.buffer)}var i=n(15),o=n(26),a=n(166),u=n(74),s=Object(i.a)("DataView");e.a=u.a?r:s},function(t,e,n){"use strict";var r=n(15),i=n(37),o=Object(r.a)("Arguments");!function(){o(arguments)||(o=function(t){return Object(i.a)(t,"callee")})}(),e.a=o},function(t,e,n){"use strict";var r=n(171);e.a=Object(r.a)("byteLength")},function(t,e,n){"use strict";function r(t){var e=Object(i.a)(t);return function(n){if(null==n)return!1;var r=Object(a.a)(n);if(Object(i.a)(r))return!1;for(var s=0;s Available in Cloud Code and Node.js only.\n * AV.Events is a fork of Backbone's Events module, provided for your\n * convenience. A module that can be mixed in to any object in order to provide\n * it with custom events. You may bind callback functions to an event\n * with `on`, or remove these functions with `off`.\n * Triggering an event fires all callbacks in the order that `on` was\n * called.\n *\n * @private\n * @example\n * var object = {};\n * _.extend(object, AV.Events);\n * object.on('expand', function(){ alert('expanded'); });\n * object.trigger('expand'); Represents a latitude / longitude point that may be associated\n * with a key in a AVObject or used as a reference point for geo queries.\n * This allows proximity-based queries on the key. Only one key in a class may contain a GeoPoint. Example: An ACL, or Access Control List can be added to any\n * \n * A class that is used to access all of the children of a many-to-many\n * relationship. Each instance of AV.Relation is associated with a\n * particular parent object and key.\n * Returns the file's metadata JSON object if no arguments is given.Returns the\n * metadata value if a key is given.Set metadata value if key and value are both given.
- 适配 React Native 示例
-
-
- ```js
- const AV = require('leancloud-storage/core');
- const reactNativeAdapters = require('@leancloud/platform-adapters-react-native');
- AV.setAdapters(reactNativeAdapters);
- ```
-
-### Bug Fixes
-
-- 修复了在浏览器中通过引入预编译的 `av-live-query.js` 引入的 SDK 抛异常的问题。这个问题是 v4.3.1 中引入的。
-
-### Internal Changes
-
-- hookKey 现在需要在初始化时传入,SDK 不再自动从环境变量获取其可能的值。
-
-## 4.3.1 (2020-03-12)
-
-这个版本继续了对「更多运行环境支持」的探索,将 SDK 内置的多平台支持使用新的 `Adapter` 模式进行了重构。SDK 支持的运行平台、使用方法都没有变化。
-
-### Bug Fixes
-
-- 修复了进行 Relation 查询时抛 `_extraOptions is undefined` 异常的问题。这个问题是 v4.0.0 中引入的。
-- `setAdaptors` 接口被重命名为 `setAdapters`。
-
-# 4.3.0 (2020-03-09)
-
-### Features
-
-- 增加了 `AV.setAdaptors`(已在 v4.3.1 中重命名为 `setAdapters`) 方法用于配置运行环境适配器。
-
- 作为正在进行的对「更多运行环境支持」探索的第一步,这个版本的 SDK 所以对平台提供的 API 的依赖被抽象为可替换的 `Adapter`。开发者可以配置全部或一部分 `Adapter` 以支持包括小程序在内的各类平台。
-
-- 为 `AV.init` 的 `serverURLs` 参数增加了一个同义参数 `serverURL`。
-
-# 4.2.0 (2020-01-07)
-
-### Features
-
-支持 QQ 小程序。
-
-- 微信小程序 SDK 现已兼容 QQ 小程序,并新增了以下登录相关的方法:
- - `AV.User.loginWithQQApp`
- - `AV.User.loginWithQQAppWithUnionId`
- - `AV.User#loginWithQQApp`
- - `AV.User#loginWithQQAppWithUnionId`
- - `AV.User#associateWithQQApp`
- - `AV.User#associateWithQQAppWithUnionId`
-
-### Bug fixes
-
-- 修复了多处 TypeScript 定义文件的错误,SDK 要求的 TypeScript 最低版本现在为 3.0。
-
-# 4.1.0 (2019-12-10)
-
-### Features
-
-- 新增了 `AV.Object#dirtyKeys` 方法获取本地修改过的属性名。`Object#hasChanged` 与 `Object#changedAttributes` 方法已被移除,请使用 `AV.Object#dirty` 与 `AV.Object#dirtyKeys` 代替。
-
-### Bug fixes
-
-- 修复了云引擎中初始化依然要求指定服务器地址的问题。
-
-## 4.0.1 (2019-12-02)
-
-### Bug fixes
-
-- 修复了指定 key fetch 时,服务端已删除的 key 没有被正确清理的问题。
-- 补充了 `AV.Cloud.useMasterKey` 的 TypeScript 定义。
-
-# 4.0.0 (2019-10-31)
-
-### BREAKING CHANGES
-
-- 对于中国节点应用,初始化 SDK 时必须通过 `serverURLs` 参数指定服务器地址。中国节点的应用必须要绑定自有域名后才能使用,这个改动是为让没有指定服务器地址时的异常更加明确。国际版应用不受影响。
-- SDK 使用的域名更新。国际版应用新增 `app-router.com`,中国节点应用不受影响。`app-router.leancloud.cn` 均不再使用。如果国际版应用在微信小程序等需要域名白名单的平台上运行,需要更新白名单配置,开发者可以访问应用的 LeanCloud 控制台获取最新的域名列表。
-- `AV.Query#toJSON` 方法现在返回完整的信息,可以通过新增的 `AV.Query.fromJSON` 方法反序列化为 `AV.Query`。原 `AV.Query#toJSON` 方法已被重命名为一个内部方法 `AV.Query#_getParams`。
-- 移除了 Bower 支持。
-
-### Features
-
-- 新增了 `AV.Query.fromJSON` 方法可以通过一个 JSON 构造一个 `AV.Query`。与 `AV.Query#toJSON` 结合可以实现在服务端与客户端之间传输 `AV.Query`。
-
-### Bug fixes
-
-- 修复了在 `AV.init` 时指定 `production` 不生效的问题。
-- 修复了多处 TypeScript 定义问题。
-
-# 3.15.0 (2019-08-05)
-
-### Features
-
-- 排行榜在获取排名结果时可以通过 `includeUserKeys` 选项同时返回 Pointer 类型的用户属性。
-
-### Bug fixes
-
-- 修复了一处导致在 Taro 中引入 SDK 抛异常的问题
-- 修复了多处 TypeScript 定义问题。
-
-## 3.14.1 (2019-07-04)
-
-### Bug fixes
-
-- 修复了 LiveQuery server 配置异常导致不可用的问题。
-
-# 3.14.0 (2019-06-30)
-
-### Features
-
-- 增加了一组序列化与反序列化方法 `AV.parse` 与 `AV.stringify`。
-- 排行榜增加了 `AV.Leaderboard#count` 方法用于获取参与排行的用户总数。
-- 增加了手动启用、停用调试模式的开关:
-
- ```js
- AV.debug.enable();
- AV.debug.disable();
- ```
-
- 原有在浏览器中使用 localStorage,在 Node.js 中使用环境变量启用调试模式的方式仍然可用。
-
-- 扩展了初始化时的 serverURLs 参数,现在允许指定 LiveQuery 服务的 server。
-
-### Bug fixes
-
-- 修正了 LiveQuery 的默认 server。
-- `AV.Query#get` 方法传入 falsy objectId 时现在有了更准确与一致的异常信息。
-- 修复了多处 TypeScript 定义问题。
-
-## 3.13.2 (2019-05-14)
-
-### Bug fixes
-
-- 修复了 `AV.Object.createWithoutData` 方法返回对象类型始终是 `AV.Object` 的问题。
-- 修复了多处 TypeScript 定义问题。
-
-## 3.13.1 (2019-05-08)
-
-### Bug fixes
-
-- 优化了 `AV.Object` 静态方法的 TypeScript 定义。
-
-# 3.13.0 (2019-04-17)
-
-### Features
-
-- 小程序用户系统增加了 UnionId 支持。
- - 一键登录 API `AV.User[.#]loginWithWeapp` 增加了新的参数 `preferUnionId`。设置了该参数为 `true` 且该小程序绑定了微信开放平台帐号,那么在满足以下条件时会自动使用用户的 UnionId 登录。
- - 微信开放平台帐号下存在同主体的公众号,并且该用户已经关注了该公众号。
- - 微信开放平台帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。
- - `AV.User#linkWithWeapp` 重命名为 `AV.User#associateWithWeapp` 与其他关联第三方 API 保持统一的命名风格。同时支持新参数 `preferUnionId`。
- - 增加了 `AV.User[.#]loginWithWeappWithUnionId` 与 `AV.User#associateWithWeappWithUnionId` 方法。用于支持开发者在通过其他方式自行拿到用户的 UnionId 后在客户端登录或关联用户。
-- 增加了 `AV.User.loginWithEmail` 方法用于明确指定使用 Email 与密码登录。
-
-### Bug fixes
-
-- `AV.File#set` 与 `AV.File#setACL` 现在会正确地返回当前实例(`this`)了。
-
-# 3.12.0 (2019-03-01)
-
-### Features
-
-- `AV.File#save` 方法增加了 `keepFileName` 方法允许保留下载文件的文件名。
-
-
- 示例
-
-
- ```js
- new AV.File('file-name.ext', source).save({ keepFileName: true });
- // https://your-file-domain/5112b94e0536e995741c/file-name.ext
-
- new AV.File('file-name.ext', source).save();
- // https://your-file-domain/5112b94e0536e995741c.ext
- ```
-
-
-Prereleases
-
-
-## 3.11.0-beta.0 (2018-08-13)
-
-### Features
-
-- 增加了 `AV.LiveQuery.pause` 与 `AV.LiveQuery.resume` 方法。这两个方法可以用于在网络变化或者应用切换后台时主动通知 SDK 断开/恢复 LiveQuery 的连接。
-
-### Bug fixes
-
-- 修复了 `AV.File#save` 方法参数不尊重 AuthOptions 类型参数的问题。
-
-0?0:a-1;u>=0&&u0?c=s>=0?s:Math.max(s+f,c):f=s>=0?Math.min(s+1,f):s+f+1;else if(n&&s&&f)return s=n(r,u),r[s]===u?s:-1;if(u!==u)return s=e(o.q.call(r,c,f),a.a),s>=0?s+c:-1;for(s=t>0?c:f-1;s>=0&&s=3;return e(t,Object(a.a)(n,i,4),r,o)}}e.a=r;var i=n(24),o=n(12),a=n(77)},function(t,e,n){"use strict";function r(t,e,n){var r,s,c=-1/0,f=-1/0;if(null==e||"number"==typeof e&&"object"!=typeof t[0]&&null!=t){t=Object(i.a)(t)?t:Object(o.a)(t);for(var l=0,d=t.length;l>>9<<4)]=s;for(var p=a._ff,v=a._gg,_=a._hh,b=a._ii,h=0;h
\n * @example\n * new GeoPoint(otherGeoPoint)\n * new GeoPoint(30, 30)\n * new GeoPoint([30, 30])\n * new GeoPoint({latitude: 30, longitude: 30})\n * new GeoPoint() // defaults to (0, 0)\n * @class\n *\n * \n * var point = new AV.GeoPoint(30.0, -20.0);\n * var object = new AV.Object(\"PlaceObject\");\n * object.set(\"location\", point);\n * object.save();
AV.Object
to restrict access to only a subset of users\n * of your application.object.set(\"foo\", \"bar\")
\n * is an example of a AV.Op.Set. Calling object.unset(\"foo\")
\n * is a AV.Op.Unset. These operations are stored in a AV.Object and\n * sent to the server as part of object.save()
operations.\n * Instances of AV.Op should be immutable.\n *\n * You should not create subclasses of AV.Op or instantiate AV.Op\n * directly.\n */\n AV.Op = function () {\n this._initialize.apply(this, arguments);\n };\n\n _.extend(AV.Op.prototype,\n /** @lends AV.Op.prototype */\n {\n _initialize: function _initialize() {}\n });\n\n _.extend(AV.Op, {\n /**\n * To create a new Op, call AV.Op._extend();\n * @private\n */\n _extend: AV._extend,\n // A map of __op string to decoder function.\n _opDecoderMap: {},\n\n /**\n * Registers a function to convert a json object with an __op field into an\n * instance of a subclass of AV.Op.\n * @private\n */\n _registerDecoder: function _registerDecoder(opName, decoder) {\n AV.Op._opDecoderMap[opName] = decoder;\n },\n\n /**\n * Converts a json object into an instance of a subclass of AV.Op.\n * @private\n */\n _decode: function _decode(json) {\n var decoder = AV.Op._opDecoderMap[json.__op];\n\n if (decoder) {\n return decoder(json);\n } else {\n return undefined;\n }\n }\n });\n /*\n * Add a handler for Batch ops.\n */\n\n\n AV.Op._registerDecoder('Batch', function (json) {\n var op = null;\n\n AV._arrayEach(json.ops, function (nextOp) {\n nextOp = AV.Op._decode(nextOp);\n op = nextOp._mergeWithPrevious(op);\n });\n\n return op;\n });\n /**\n * @private\n * @class\n * A Set operation indicates that either the field was changed using\n * AV.Object.set, or it is a mutable container that was detected as being\n * changed.\n */\n\n\n AV.Op.Set = AV.Op._extend(\n /** @lends AV.Op.Set.prototype */\n {\n _initialize: function _initialize(value) {\n this._value = value;\n },\n\n /**\n * Returns the new value of this field after the set.\n */\n value: function value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return AV._encode(this.value());\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n return this;\n },\n _estimate: function _estimate(oldValue) {\n return this.value();\n }\n });\n /**\n * A sentinel value that is returned by AV.Op.Unset._estimate to\n * indicate the field should be deleted. Basically, if you find _UNSET as a\n * value in your object, you should remove that key.\n */\n\n AV.Op._UNSET = {};\n /**\n * @private\n * @class\n * An Unset operation indicates that this field has been deleted from the\n * object.\n */\n\n AV.Op.Unset = AV.Op._extend(\n /** @lends AV.Op.Unset.prototype */\n {\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'Delete'\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n return this;\n },\n _estimate: function _estimate(oldValue) {\n return AV.Op._UNSET;\n }\n });\n\n AV.Op._registerDecoder('Delete', function (json) {\n return new AV.Op.Unset();\n });\n /**\n * @private\n * @class\n * An Increment is an atomic operation where the numeric value for the field\n * will be increased by a given amount.\n */\n\n\n AV.Op.Increment = AV.Op._extend(\n /** @lends AV.Op.Increment.prototype */\n {\n _initialize: function _initialize(amount) {\n this._amount = amount;\n },\n\n /**\n * Returns the amount to increment by.\n * @return {Number} the amount to increment by.\n */\n amount: function amount() {\n return this._amount;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'Increment',\n amount: this._amount\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.amount());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() + this.amount());\n } else if (previous instanceof AV.Op.Increment) {\n return new AV.Op.Increment(this.amount() + previous.amount());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue) {\n if (!oldValue) {\n return this.amount();\n }\n\n return oldValue + this.amount();\n }\n });\n\n AV.Op._registerDecoder('Increment', function (json) {\n return new AV.Op.Increment(json.amount);\n });\n /**\n * @private\n * @class\n * BitAnd is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n\n\n AV.Op.BitAnd = AV.Op._extend(\n /** @lends AV.Op.BitAnd.prototype */\n {\n _initialize: function _initialize(value) {\n this._value = value;\n },\n value: function value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'BitAnd',\n value: this.value()\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(0);\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() & this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue) {\n return oldValue & this.value();\n }\n });\n\n AV.Op._registerDecoder('BitAnd', function (json) {\n return new AV.Op.BitAnd(json.value);\n });\n /**\n * @private\n * @class\n * BitOr is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n\n\n AV.Op.BitOr = AV.Op._extend(\n /** @lends AV.Op.BitOr.prototype */\n {\n _initialize: function _initialize(value) {\n this._value = value;\n },\n value: function value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'BitOr',\n value: this.value()\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.value());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() | this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue) {\n return oldValue | this.value();\n }\n });\n\n AV.Op._registerDecoder('BitOr', function (json) {\n return new AV.Op.BitOr(json.value);\n });\n /**\n * @private\n * @class\n * BitXor is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n\n\n AV.Op.BitXor = AV.Op._extend(\n /** @lends AV.Op.BitXor.prototype */\n {\n _initialize: function _initialize(value) {\n this._value = value;\n },\n value: function value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'BitXor',\n value: this.value()\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.value());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() ^ this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue) {\n return oldValue ^ this.value();\n }\n });\n\n AV.Op._registerDecoder('BitXor', function (json) {\n return new AV.Op.BitXor(json.value);\n });\n /**\n * @private\n * @class\n * Add is an atomic operation where the given objects will be appended to the\n * array that is stored in this field.\n */\n\n\n AV.Op.Add = AV.Op._extend(\n /** @lends AV.Op.Add.prototype */\n {\n _initialize: function _initialize(objects) {\n this._objects = objects;\n },\n\n /**\n * Returns the objects to be added to the array.\n * @return {Array} The objects to be added to the array.\n */\n objects: function objects() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'Add',\n objects: AV._encode(this.objects())\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.objects());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.Add) {\n var _context;\n\n return new AV.Op.Add((0, _concat.default)(_context = previous.objects()).call(_context, this.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue) {\n if (!oldValue) {\n return _.clone(this.objects());\n } else {\n return (0, _concat.default)(oldValue).call(oldValue, this.objects());\n }\n }\n });\n\n AV.Op._registerDecoder('Add', function (json) {\n return new AV.Op.Add(AV._decode(json.objects));\n });\n /**\n * @private\n * @class\n * AddUnique is an atomic operation where the given items will be appended to\n * the array that is stored in this field only if they were not already\n * present in the array.\n */\n\n\n AV.Op.AddUnique = AV.Op._extend(\n /** @lends AV.Op.AddUnique.prototype */\n {\n _initialize: function _initialize(objects) {\n this._objects = _.uniq(objects);\n },\n\n /**\n * Returns the objects to be added to the array.\n * @return {Array} The objects to be added to the array.\n */\n objects: function objects() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'AddUnique',\n objects: AV._encode(this.objects())\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.objects());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.AddUnique) {\n return new AV.Op.AddUnique(this._estimate(previous.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue) {\n if (!oldValue) {\n return _.clone(this.objects());\n } else {\n // We can't just take the _.uniq(_.union(...)) of oldValue and\n // this.objects, because the uniqueness may not apply to oldValue\n // (especially if the oldValue was set via .set())\n var newValue = _.clone(oldValue);\n\n AV._arrayEach(this.objects(), function (obj) {\n if (obj instanceof AV.Object && obj.id) {\n var matchingObj = (0, _find.default)(_).call(_, newValue, function (anObj) {\n return anObj instanceof AV.Object && anObj.id === obj.id;\n });\n\n if (!matchingObj) {\n newValue.push(obj);\n } else {\n var index = (0, _indexOf.default)(_).call(_, newValue, matchingObj);\n newValue[index] = obj;\n }\n } else if (!_.contains(newValue, obj)) {\n newValue.push(obj);\n }\n });\n\n return newValue;\n }\n }\n });\n\n AV.Op._registerDecoder('AddUnique', function (json) {\n return new AV.Op.AddUnique(AV._decode(json.objects));\n });\n /**\n * @private\n * @class\n * Remove is an atomic operation where the given objects will be removed from\n * the array that is stored in this field.\n */\n\n\n AV.Op.Remove = AV.Op._extend(\n /** @lends AV.Op.Remove.prototype */\n {\n _initialize: function _initialize(objects) {\n this._objects = _.uniq(objects);\n },\n\n /**\n * Returns the objects to be removed from the array.\n * @return {Array} The objects to be removed from the array.\n */\n objects: function objects() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n return {\n __op: 'Remove',\n objects: AV._encode(this.objects())\n };\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return previous;\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.Remove) {\n return new AV.Op.Remove(_.union(previous.objects(), this.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue) {\n if (!oldValue) {\n return [];\n } else {\n var newValue = _.difference(oldValue, this.objects()); // If there are saved AV Objects being removed, also remove them.\n\n\n AV._arrayEach(this.objects(), function (obj) {\n if (obj instanceof AV.Object && obj.id) {\n newValue = _.reject(newValue, function (other) {\n return other instanceof AV.Object && other.id === obj.id;\n });\n }\n });\n\n return newValue;\n }\n }\n });\n\n AV.Op._registerDecoder('Remove', function (json) {\n return new AV.Op.Remove(AV._decode(json.objects));\n });\n /**\n * @private\n * @class\n * A Relation operation indicates that the field is an instance of\n * AV.Relation, and objects are being added to, or removed from, that\n * relation.\n */\n\n\n AV.Op.Relation = AV.Op._extend(\n /** @lends AV.Op.Relation.prototype */\n {\n _initialize: function _initialize(adds, removes) {\n this._targetClassName = null;\n var self = this;\n\n var pointerToId = function pointerToId(object) {\n if (object instanceof AV.Object) {\n if (!object.id) {\n throw new Error(\"You can't add an unsaved AV.Object to a relation.\");\n }\n\n if (!self._targetClassName) {\n self._targetClassName = object.className;\n }\n\n if (self._targetClassName !== object.className) {\n throw new Error('Tried to create a AV.Relation with 2 different types: ' + self._targetClassName + ' and ' + object.className + '.');\n }\n\n return object.id;\n }\n\n return object;\n };\n\n this.relationsToAdd = _.uniq((0, _map.default)(_).call(_, adds, pointerToId));\n this.relationsToRemove = _.uniq((0, _map.default)(_).call(_, removes, pointerToId));\n },\n\n /**\n * Returns an array of unfetched AV.Object that are being added to the\n * relation.\n * @return {Array}\n */\n added: function added() {\n var self = this;\n return (0, _map.default)(_).call(_, this.relationsToAdd, function (objectId) {\n var object = AV.Object._create(self._targetClassName);\n\n object.id = objectId;\n return object;\n });\n },\n\n /**\n * Returns an array of unfetched AV.Object that are being removed from\n * the relation.\n * @return {Array}\n */\n removed: function removed() {\n var self = this;\n return (0, _map.default)(_).call(_, this.relationsToRemove, function (objectId) {\n var object = AV.Object._create(self._targetClassName);\n\n object.id = objectId;\n return object;\n });\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function toJSON() {\n var adds = null;\n var removes = null;\n var self = this;\n\n var idToPointer = function idToPointer(id) {\n return {\n __type: 'Pointer',\n className: self._targetClassName,\n objectId: id\n };\n };\n\n var pointers = null;\n\n if (this.relationsToAdd.length > 0) {\n pointers = (0, _map.default)(_).call(_, this.relationsToAdd, idToPointer);\n adds = {\n __op: 'AddRelation',\n objects: pointers\n };\n }\n\n if (this.relationsToRemove.length > 0) {\n pointers = (0, _map.default)(_).call(_, this.relationsToRemove, idToPointer);\n removes = {\n __op: 'RemoveRelation',\n objects: pointers\n };\n }\n\n if (adds && removes) {\n return {\n __op: 'Batch',\n ops: [adds, removes]\n };\n }\n\n return adds || removes || {};\n },\n _mergeWithPrevious: function _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n throw new Error(\"You can't modify a relation after deleting it.\");\n } else if (previous instanceof AV.Op.Relation) {\n if (previous._targetClassName && previous._targetClassName !== this._targetClassName) {\n throw new Error('Related object must be of class ' + previous._targetClassName + ', but ' + this._targetClassName + ' was passed in.');\n }\n\n var newAdd = _.union(_.difference(previous.relationsToAdd, this.relationsToRemove), this.relationsToAdd);\n\n var newRemove = _.union(_.difference(previous.relationsToRemove, this.relationsToAdd), this.relationsToRemove);\n\n var newRelation = new AV.Op.Relation(newAdd, newRemove);\n newRelation._targetClassName = this._targetClassName;\n return newRelation;\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n _estimate: function _estimate(oldValue, object, key) {\n if (!oldValue) {\n var relation = new AV.Relation(object, key);\n relation.targetClassName = this._targetClassName;\n } else if (oldValue instanceof AV.Relation) {\n if (this._targetClassName) {\n if (oldValue.targetClassName) {\n if (oldValue.targetClassName !== this._targetClassName) {\n throw new Error('Related object must be a ' + oldValue.targetClassName + ', but a ' + this._targetClassName + ' was passed in.');\n }\n } else {\n oldValue.targetClassName = this._targetClassName;\n }\n }\n\n return oldValue;\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n }\n });\n\n AV.Op._registerDecoder('AddRelation', function (json) {\n return new AV.Op.Relation(AV._decode(json.objects), []);\n });\n\n AV.Op._registerDecoder('RemoveRelation', function (json) {\n return new AV.Op.Relation([], AV._decode(json.objects));\n });\n};\n\n/***/ }),\n/* 440 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(441);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 441 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isPrototypeOf = __webpack_require__(20);\nvar method = __webpack_require__(442);\n\nvar ArrayPrototype = Array.prototype;\n\nmodule.exports = function (it) {\n var own = it.find;\n return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.find) ? method : own;\n};\n\n\n/***/ }),\n/* 442 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(443);\nvar entryVirtual = __webpack_require__(38);\n\nmodule.exports = entryVirtual('Array').find;\n\n\n/***/ }),\n/* 443 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $ = __webpack_require__(0);\nvar $find = __webpack_require__(101).find;\nvar addToUnscopables = __webpack_require__(152);\n\nvar FIND = 'find';\nvar SKIPS_HOLES = true;\n\n// Shouldn't skip holes\nif (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });\n\n// `Array.prototype.find` method\n// https://tc39.es/ecma262/#sec-array.prototype.find\n$({ target: 'Array', proto: true, forced: SKIPS_HOLES }, {\n find: function find(callbackfn /* , that = undefined */) {\n return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables(FIND);\n\n\n/***/ }),\n/* 444 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _ = __webpack_require__(1);\n\nmodule.exports = function (AV) {\n /**\n * Creates a new Relation for the given parent object and key. This\n * constructor should rarely be used directly, but rather created by\n * {@link AV.Object#relation}.\n * @param {AV.Object} parent The parent of this relation.\n * @param {String} key The key for this relation on the parent.\n * @see AV.Object#relation\n * @class\n *\n * \n * var fileUploadControl = $(\"#profilePhotoFileUpload\")[0];\n * if (fileUploadControl.files.length > 0) {\n * var file = fileUploadControl.files[0];\n * var name = \"photo.jpg\";\n * var file = new AV.File(name, file);\n * file.save().then(function() {\n * // The file has been saved to AV.\n * }, function(error) {\n * // The file either could not be read, or could not be saved to AV.\n * });\n * }
\n *\n * @class\n * @param [mimeType] {String} Content-Type header to use for the file. If\n * this is omitted, the content type will be inferred from the name's\n * extension.\n */\n\n\n AV.File = function (name, data, mimeType) {\n this.attributes = {\n name: name,\n url: '',\n metaData: {},\n // 用来存储转换后要上传的 base64 String\n base64: ''\n };\n\n if (_.isString(data)) {\n throw new TypeError('Creating an AV.File from a String is not yet supported.');\n }\n\n if (_.isArray(data)) {\n this.attributes.metaData.size = data.length;\n data = {\n base64: encodeBase64(data)\n };\n }\n\n this._extName = '';\n this._data = data;\n this._uploadHeaders = {};\n\n if (data && data.blob && typeof data.blob.uri === 'string') {\n this._extName = extname(data.blob.uri);\n }\n\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n if (data.size) {\n this.attributes.metaData.size = data.size;\n }\n\n if (data.name) {\n this._extName = extname(data.name);\n }\n }\n\n var owner;\n\n if (data && data.owner) {\n owner = data.owner;\n } else if (!AV._config.disableCurrentUser) {\n try {\n owner = AV.User.current();\n } catch (error) {\n if ('SYNC_API_NOT_AVAILABLE' !== error.code) {\n throw error;\n }\n }\n }\n\n this.attributes.metaData.owner = owner ? owner.id : 'unknown';\n this.set('mime_type', mimeType);\n };\n /**\n * Creates a fresh AV.File object with exists url for saving to AVOS Cloud.\n * @param {String} name the file name\n * @param {String} url the file url.\n * @param {Object} [metaData] the file metadata object.\n * @param {String} [type] Content-Type header to use for the file. If\n * this is omitted, the content type will be inferred from the name's\n * extension.\n * @return {AV.File} the file object\n */\n\n\n AV.File.withURL = function (name, url, metaData, type) {\n if (!name || !url) {\n throw new Error('Please provide file name and url');\n }\n\n var file = new AV.File(name, null, type); //copy metaData properties to file.\n\n if (metaData) {\n for (var prop in metaData) {\n if (!file.attributes.metaData[prop]) file.attributes.metaData[prop] = metaData[prop];\n }\n }\n\n file.attributes.url = url; //Mark the file is from external source.\n\n file.attributes.metaData.__source = 'external';\n file.attributes.metaData.size = 0;\n return file;\n };\n /**\n * Creates a file object with exists objectId.\n * @param {String} objectId The objectId string\n * @return {AV.File} the file object\n */\n\n\n AV.File.createWithoutData = function (objectId) {\n if (!objectId) {\n throw new TypeError('The objectId must be provided');\n }\n\n var file = new AV.File();\n file.id = objectId;\n return file;\n };\n /**\n * Request file censor.\n * @since 4.13.0\n * @param {String} objectId\n * @return {Promise.\n * var metadata = file.metaData(); //Get metadata JSON object.\n * var size = file.metaData('size'); // Get the size metadata value.\n * file.metaData('format', 'jpeg'); //set metadata attribute and value.\n *
You won't normally call this method directly. It is recommended that\n * you use a subclass of AV.Object
instead, created by calling\n * extend
.
However, if you don't want to use a subclass, or aren't sure which\n * subclass is appropriate, you can use this form:
\n * var object = new AV.Object(\"ClassName\");\n *\n * That is basically equivalent to:
\n * var MyClass = AV.Object.extend(\"ClassName\");\n * var object = new MyClass();\n *\n *\n * @param {Object} attributes The initial set of data to store in the object.\n * @param {Object} options A set of Backbone-like options for creating the\n * object. The only option currently supported is \"collection\".\n * @see AV.Object.extend\n *\n * @class\n *\n *
The fundamental unit of AV data, which implements the Backbone Model\n * interface.
\n */\n AV.Object = function (attributes, options) {\n // Allow new AV.Object(\"ClassName\") as a shortcut to _create.\n if (_.isString(attributes)) {\n return AV.Object._create.apply(this, arguments);\n }\n\n attributes = attributes || {};\n\n if (options && options.parse) {\n attributes = this.parse(attributes);\n attributes = this._mergeMagicFields(attributes);\n }\n\n var defaults = getValue(this, 'defaults');\n\n if (defaults) {\n attributes = _.extend({}, defaults, attributes);\n }\n\n if (options && options.collection) {\n this.collection = options.collection;\n }\n\n this._serverData = {}; // The last known data for this object from cloud.\n\n this._opSetQueue = [{}]; // List of sets of changes to the data.\n\n this._flags = {};\n this.attributes = {}; // The best estimate of this's current data.\n\n this._hashedJSON = {}; // Hash of values of containers at last save.\n\n this._escapedAttributes = {};\n this.cid = _.uniqueId('c');\n this.changed = {};\n this._silent = {};\n this._pending = {};\n this.set(attributes, {\n silent: true\n });\n this.changed = {};\n this._silent = {};\n this._pending = {};\n this._hasData = true;\n this._previousAttributes = _.clone(this.attributes);\n this.initialize.apply(this, arguments);\n };\n /**\n * @lends AV.Object.prototype\n * @property {String} id The objectId of the AV Object.\n */\n\n /**\n * Saves the given list of AV.Object.\n * If any error is encountered, stops and calls the error handler.\n *\n * @example\n * AV.Object.saveAll([object1, object2, ...]).then(function(list) {\n * // All the objects were saved.\n * }, function(error) {\n * // An error occurred while saving one of the objects.\n * });\n *\n * @param {Array} list A list ofAV.Object
.\n */\n\n\n AV.Object.saveAll = function (list, options) {\n return AV.Object._deepSaveAsync(list, null, options);\n };\n /**\n * Fetch the given list of AV.Object.\n *\n * @param {AV.Object[]} objects A list of AV.Object
\n * @param {AuthOptions} options\n * @return {Promise.AV.Object
, updated\n */\n\n\n AV.Object.fetchAll = function (objects, options) {\n return _promise.default.resolve().then(function () {\n return _request('batch', null, null, 'POST', {\n requests: (0, _map.default)(_).call(_, objects, function (object) {\n var _context;\n\n if (!object.className) throw new Error('object must have className to fetch');\n if (!object.id) throw new Error('object must have id to fetch');\n if (object.dirty()) throw new Error('object is modified but not saved');\n return {\n method: 'GET',\n path: (0, _concat.default)(_context = \"/1.1/classes/\".concat(object.className, \"/\")).call(_context, object.id)\n };\n })\n }, options);\n }).then(function (response) {\n var results = (0, _map.default)(_).call(_, objects, function (object, i) {\n if (response[i].success) {\n var fetchedAttrs = object.parse(response[i].success);\n\n object._cleanupUnsetKeys(fetchedAttrs);\n\n object._finishFetch(fetchedAttrs);\n\n return object;\n }\n\n if (response[i].success === null) {\n return new AVError(AVError.OBJECT_NOT_FOUND, 'Object not found.');\n }\n\n return new AVError(response[i].error.code, response[i].error.error);\n });\n return handleBatchResults(results);\n });\n }; // Attach all inheritable methods to the AV.Object prototype.\n\n\n _.extend(AV.Object.prototype, AV.Events,\n /** @lends AV.Object.prototype */\n {\n _fetchWhenSave: false,\n\n /**\n * Initialize is an empty function by default. Override it with your own\n * initialization logic.\n */\n initialize: function initialize() {},\n\n /**\n * Set whether to enable fetchWhenSave option when updating object.\n * When set true, SDK would fetch the latest object after saving.\n * Default is false.\n *\n * @deprecated use AV.Object#save with options.fetchWhenSave instead\n * @param {boolean} enable true to enable fetchWhenSave option.\n */\n fetchWhenSave: function fetchWhenSave(enable) {\n console.warn('AV.Object#fetchWhenSave is deprecated, use AV.Object#save with options.fetchWhenSave instead.');\n\n if (!_.isBoolean(enable)) {\n throw new Error('Expect boolean value for fetchWhenSave');\n }\n\n this._fetchWhenSave = enable;\n },\n\n /**\n * Returns the object's objectId.\n * @return {String} the objectId.\n */\n getObjectId: function getObjectId() {\n return this.id;\n },\n\n /**\n * Returns the object's createdAt attribute.\n * @return {Date}\n */\n getCreatedAt: function getCreatedAt() {\n return this.createdAt;\n },\n\n /**\n * Returns the object's updatedAt attribute.\n * @return {Date}\n */\n getUpdatedAt: function getUpdatedAt() {\n return this.updatedAt;\n },\n\n /**\n * Returns a JSON version of the object.\n * @return {Object}\n */\n toJSON: function toJSON(key, holder) {\n var seenObjects = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n return this._toFullJSON(seenObjects, false);\n },\n\n /**\n * Returns a JSON version of the object with meta data.\n * Inverse to {@link AV.parseJSON}\n * @since 3.0.0\n * @return {Object}\n */\n toFullJSON: function toFullJSON() {\n var seenObjects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return this._toFullJSON(seenObjects);\n },\n _toFullJSON: function _toFullJSON(seenObjects) {\n var _this = this;\n\n var full = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n var json = _.clone(this.attributes);\n\n if (_.isArray(seenObjects)) {\n var newSeenObjects = (0, _concat.default)(seenObjects).call(seenObjects, this);\n }\n\n AV._objectEach(json, function (val, key) {\n json[key] = AV._encode(val, newSeenObjects, undefined, full);\n });\n\n AV._objectEach(this._operations, function (val, key) {\n json[key] = val;\n });\n\n if (_.has(this, 'id')) {\n json.objectId = this.id;\n }\n\n ['createdAt', 'updatedAt'].forEach(function (key) {\n if (_.has(_this, key)) {\n var val = _this[key];\n json[key] = _.isDate(val) ? val.toJSON() : val;\n }\n });\n\n if (full) {\n json.__type = 'Object';\n if (_.isArray(seenObjects) && seenObjects.length) json.__type = 'Pointer';\n json.className = this.className;\n }\n\n return json;\n },\n\n /**\n * Updates _hashedJSON to reflect the current state of this object.\n * Adds any changed hash values to the set of pending changes.\n * @private\n */\n _refreshCache: function _refreshCache() {\n var self = this;\n\n if (self._refreshingCache) {\n return;\n }\n\n self._refreshingCache = true;\n\n AV._objectEach(this.attributes, function (value, key) {\n if (value instanceof AV.Object) {\n value._refreshCache();\n } else if (_.isObject(value)) {\n if (self._resetCacheForKey(key)) {\n self.set(key, new AV.Op.Set(value), {\n silent: true\n });\n }\n }\n });\n\n delete self._refreshingCache;\n },\n\n /**\n * Returns true if this object has been modified since its last\n * save/refresh. If an attribute is specified, it returns true only if that\n * particular attribute has been modified since the last save/refresh.\n * @param {String} attr An attribute name (optional).\n * @return {Boolean}\n */\n dirty: function dirty(attr) {\n this._refreshCache();\n\n var currentChanges = _.last(this._opSetQueue);\n\n if (attr) {\n return currentChanges[attr] ? true : false;\n }\n\n if (!this.id) {\n return true;\n }\n\n if ((0, _keys2.default)(_).call(_, currentChanges).length > 0) {\n return true;\n }\n\n return false;\n },\n\n /**\n * Returns the keys of the modified attribute since its last save/refresh.\n * @return {String[]}\n */\n dirtyKeys: function dirtyKeys() {\n this._refreshCache();\n\n var currentChanges = _.last(this._opSetQueue);\n\n return (0, _keys2.default)(_).call(_, currentChanges);\n },\n\n /**\n * Gets a Pointer referencing this Object.\n * @private\n */\n _toPointer: function _toPointer() {\n // if (!this.id) {\n // throw new Error(\"Can't serialize an unsaved AV.Object\");\n // }\n return {\n __type: 'Pointer',\n className: this.className,\n objectId: this.id\n };\n },\n\n /**\n * Gets the value of an attribute.\n * @param {String} attr The string name of an attribute.\n */\n get: function get(attr) {\n switch (attr) {\n case 'objectId':\n return this.id;\n\n case 'createdAt':\n case 'updatedAt':\n return this[attr];\n\n default:\n return this.attributes[attr];\n }\n },\n\n /**\n * Gets a relation on the given class for the attribute.\n * @param {String} attr The attribute to get the relation for.\n * @return {AV.Relation}\n */\n relation: function relation(attr) {\n var value = this.get(attr);\n\n if (value) {\n if (!(value instanceof AV.Relation)) {\n throw new Error('Called relation() on non-relation field ' + attr);\n }\n\n value._ensureParentAndKey(this, attr);\n\n return value;\n } else {\n return new AV.Relation(this, attr);\n }\n },\n\n /**\n * Gets the HTML-escaped value of an attribute.\n */\n escape: function escape(attr) {\n var html = this._escapedAttributes[attr];\n\n if (html) {\n return html;\n }\n\n var val = this.attributes[attr];\n var escaped;\n\n if (isNullOrUndefined(val)) {\n escaped = '';\n } else {\n escaped = _.escape(val.toString());\n }\n\n this._escapedAttributes[attr] = escaped;\n return escaped;\n },\n\n /**\n * Returns true
if the attribute contains a value that is not\n * null or undefined.\n * @param {String} attr The string name of the attribute.\n * @return {Boolean}\n */\n has: function has(attr) {\n return !isNullOrUndefined(this.attributes[attr]);\n },\n\n /**\n * Pulls \"special\" fields like objectId, createdAt, etc. out of attrs\n * and puts them on \"this\" directly. Removes them from attrs.\n * @param attrs - A dictionary with the data for this AV.Object.\n * @private\n */\n _mergeMagicFields: function _mergeMagicFields(attrs) {\n // Check for changes of magic fields.\n var model = this;\n var specialFields = ['objectId', 'createdAt', 'updatedAt'];\n\n AV._arrayEach(specialFields, function (attr) {\n if (attrs[attr]) {\n if (attr === 'objectId') {\n model.id = attrs[attr];\n } else if ((attr === 'createdAt' || attr === 'updatedAt') && !_.isDate(attrs[attr])) {\n model[attr] = AV._parseDate(attrs[attr]);\n } else {\n model[attr] = attrs[attr];\n }\n\n delete attrs[attr];\n }\n });\n\n return attrs;\n },\n\n /**\n * Returns the json to be sent to the server.\n * @private\n */\n _startSave: function _startSave() {\n this._opSetQueue.push({});\n },\n\n /**\n * Called when a save fails because of an error. Any changes that were part\n * of the save need to be merged with changes made after the save. This\n * might throw an exception is you do conflicting operations. For example,\n * if you do:\n * object.set(\"foo\", \"bar\");\n * object.set(\"invalid field name\", \"baz\");\n * object.save();\n * object.increment(\"foo\");\n * then this will throw when the save fails and the client tries to merge\n * \"bar\" with the +1.\n * @private\n */\n _cancelSave: function _cancelSave() {\n var failedChanges = _.first(this._opSetQueue);\n\n this._opSetQueue = _.rest(this._opSetQueue);\n\n var nextChanges = _.first(this._opSetQueue);\n\n AV._objectEach(failedChanges, function (op, key) {\n var op1 = failedChanges[key];\n var op2 = nextChanges[key];\n\n if (op1 && op2) {\n nextChanges[key] = op2._mergeWithPrevious(op1);\n } else if (op1) {\n nextChanges[key] = op1;\n }\n });\n\n this._saving = this._saving - 1;\n },\n\n /**\n * Called when a save completes successfully. This merges the changes that\n * were saved into the known server data, and overrides it with any data\n * sent directly from the server.\n * @private\n */\n _finishSave: function _finishSave(serverData) {\n var _context2;\n\n // Grab a copy of any object referenced by this object. These instances\n // may have already been fetched, and we don't want to lose their data.\n // Note that doing it like this means we will unify separate copies of the\n // same object, but that's a risk we have to take.\n var fetchedObjects = {};\n\n AV._traverse(this.attributes, function (object) {\n if (object instanceof AV.Object && object.id && object._hasData) {\n fetchedObjects[object.id] = object;\n }\n });\n\n var savedChanges = _.first(this._opSetQueue);\n\n this._opSetQueue = _.rest(this._opSetQueue);\n\n this._applyOpSet(savedChanges, this._serverData);\n\n this._mergeMagicFields(serverData);\n\n var self = this;\n\n AV._objectEach(serverData, function (value, key) {\n self._serverData[key] = AV._decode(value, key); // Look for any objects that might have become unfetched and fix them\n // by replacing their values with the previously observed values.\n\n var fetched = AV._traverse(self._serverData[key], function (object) {\n if (object instanceof AV.Object && fetchedObjects[object.id]) {\n return fetchedObjects[object.id];\n }\n });\n\n if (fetched) {\n self._serverData[key] = fetched;\n }\n });\n\n this._rebuildAllEstimatedData();\n\n var opSetQueue = (0, _map.default)(_context2 = this._opSetQueue).call(_context2, _.clone);\n\n this._refreshCache();\n\n this._opSetQueue = opSetQueue;\n this._saving = this._saving - 1;\n },\n\n /**\n * Called when a fetch or login is complete to set the known server data to\n * the given object.\n * @private\n */\n _finishFetch: function _finishFetch(serverData, hasData) {\n // Clear out any changes the user might have made previously.\n this._opSetQueue = [{}]; // Bring in all the new server data.\n\n this._mergeMagicFields(serverData);\n\n var self = this;\n\n AV._objectEach(serverData, function (value, key) {\n self._serverData[key] = AV._decode(value, key);\n }); // Refresh the attributes.\n\n\n this._rebuildAllEstimatedData(); // Clear out the cache of mutable containers.\n\n\n this._refreshCache();\n\n this._opSetQueue = [{}];\n this._hasData = hasData;\n },\n\n /**\n * Applies the set of AV.Op in opSet to the object target.\n * @private\n */\n _applyOpSet: function _applyOpSet(opSet, target) {\n var self = this;\n\n AV._objectEach(opSet, function (change, key) {\n var _findValue = findValue(target, key),\n _findValue2 = (0, _slicedToArray2.default)(_findValue, 3),\n value = _findValue2[0],\n actualTarget = _findValue2[1],\n actualKey = _findValue2[2];\n\n setValue(target, key, change._estimate(value, self, key));\n\n if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {\n delete actualTarget[actualKey];\n }\n });\n },\n\n /**\n * Replaces the cached value for key with the current value.\n * Returns true if the new value is different than the old value.\n * @private\n */\n _resetCacheForKey: function _resetCacheForKey(key) {\n var value = this.attributes[key];\n\n if (_.isObject(value) && !(value instanceof AV.Object) && !(value instanceof AV.File)) {\n var json = (0, _stringify.default)(recursiveToPointer(value));\n\n if (this._hashedJSON[key] !== json) {\n var wasSet = !!this._hashedJSON[key];\n this._hashedJSON[key] = json;\n return wasSet;\n }\n }\n\n return false;\n },\n\n /**\n * Populates attributes[key] by starting with the last known data from the\n * server, and applying all of the local changes that have been made to that\n * key since then.\n * @private\n */\n _rebuildEstimatedDataForKey: function _rebuildEstimatedDataForKey(key) {\n var self = this;\n delete this.attributes[key];\n\n if (this._serverData[key]) {\n this.attributes[key] = this._serverData[key];\n }\n\n AV._arrayEach(this._opSetQueue, function (opSet) {\n var op = opSet[key];\n\n if (op) {\n var _findValue3 = findValue(self.attributes, key),\n _findValue4 = (0, _slicedToArray2.default)(_findValue3, 4),\n value = _findValue4[0],\n actualTarget = _findValue4[1],\n actualKey = _findValue4[2],\n firstKey = _findValue4[3];\n\n setValue(self.attributes, key, op._estimate(value, self, key));\n\n if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {\n delete actualTarget[actualKey];\n }\n\n self._resetCacheForKey(firstKey);\n }\n });\n },\n\n /**\n * Populates attributes by starting with the last known data from the\n * server, and applying all of the local changes that have been made since\n * then.\n * @private\n */\n _rebuildAllEstimatedData: function _rebuildAllEstimatedData() {\n var self = this;\n\n var previousAttributes = _.clone(this.attributes);\n\n this.attributes = _.clone(this._serverData);\n\n AV._arrayEach(this._opSetQueue, function (opSet) {\n self._applyOpSet(opSet, self.attributes);\n\n AV._objectEach(opSet, function (op, key) {\n self._resetCacheForKey(key);\n });\n }); // Trigger change events for anything that changed because of the fetch.\n\n\n AV._objectEach(previousAttributes, function (oldValue, key) {\n if (self.attributes[key] !== oldValue) {\n self.trigger('change:' + key, self, self.attributes[key], {});\n }\n });\n\n AV._objectEach(this.attributes, function (newValue, key) {\n if (!_.has(previousAttributes, key)) {\n self.trigger('change:' + key, self, newValue, {});\n }\n });\n },\n\n /**\n * Sets a hash of model attributes on the object, firing\n * \"change\"
unless you choose to silence it.\n *\n * You can call it with an object containing keys and values, or with one\n * key and value. For example:
\n *\n * @example\n * gameTurn.set({\n * player: player1,\n * diceRoll: 2\n * });\n *\n * game.set(\"currentPlayer\", player2);\n *\n * game.set(\"finished\", true);\n *\n * @param {String} key The key to set.\n * @param {Any} value The value to give it.\n * @param {Object} [options]\n * @param {Boolean} [options.silent]\n * @return {AV.Object} self if succeeded, throws if the value is not valid.\n * @see AV.Object#validate\n */\n set: function set(key, value, options) {\n var attrs;\n\n if (_.isObject(key) || isNullOrUndefined(key)) {\n attrs = _.mapObject(key, function (v, k) {\n checkReservedKey(k);\n return AV._decode(v, k);\n });\n options = value;\n } else {\n attrs = {};\n checkReservedKey(key);\n attrs[key] = AV._decode(value, key);\n } // Extract attributes and options.\n\n\n options = options || {};\n\n if (!attrs) {\n return this;\n }\n\n if (attrs instanceof AV.Object) {\n attrs = attrs.attributes;\n } // If the unset option is used, every attribute should be a Unset.\n\n\n if (options.unset) {\n AV._objectEach(attrs, function (unused_value, key) {\n attrs[key] = new AV.Op.Unset();\n });\n } // Apply all the attributes to get the estimated values.\n\n\n var dataToValidate = _.clone(attrs);\n\n var self = this;\n\n AV._objectEach(dataToValidate, function (value, key) {\n if (value instanceof AV.Op) {\n dataToValidate[key] = value._estimate(self.attributes[key], self, key);\n\n if (dataToValidate[key] === AV.Op._UNSET) {\n delete dataToValidate[key];\n }\n }\n }); // Run validation.\n\n\n this._validate(attrs, options);\n\n options.changes = {};\n var escaped = this._escapedAttributes; // Update attributes.\n\n AV._arrayEach((0, _keys2.default)(_).call(_, attrs), function (attr) {\n var val = attrs[attr]; // If this is a relation object we need to set the parent correctly,\n // since the location where it was parsed does not have access to\n // this object.\n\n if (val instanceof AV.Relation) {\n val.parent = self;\n }\n\n if (!(val instanceof AV.Op)) {\n val = new AV.Op.Set(val);\n } // See if this change will actually have any effect.\n\n\n var isRealChange = true;\n\n if (val instanceof AV.Op.Set && _.isEqual(self.attributes[attr], val.value)) {\n isRealChange = false;\n }\n\n if (isRealChange) {\n delete escaped[attr];\n\n if (options.silent) {\n self._silent[attr] = true;\n } else {\n options.changes[attr] = true;\n }\n }\n\n var currentChanges = _.last(self._opSetQueue);\n\n currentChanges[attr] = val._mergeWithPrevious(currentChanges[attr]);\n\n self._rebuildEstimatedDataForKey(attr);\n\n if (isRealChange) {\n self.changed[attr] = self.attributes[attr];\n\n if (!options.silent) {\n self._pending[attr] = true;\n }\n } else {\n delete self.changed[attr];\n delete self._pending[attr];\n }\n });\n\n if (!options.silent) {\n this.change(options);\n }\n\n return this;\n },\n\n /**\n * Remove an attribute from the model, firing\"change\"
unless\n * you choose to silence it. This is a noop if the attribute doesn't\n * exist.\n * @param key {String} The key.\n */\n unset: function unset(attr, options) {\n options = options || {};\n options.unset = true;\n return this.set(attr, null, options);\n },\n\n /**\n * Atomically increments the value of the given attribute the next time the\n * object is saved. If no amount is specified, 1 is used by default.\n *\n * @param key {String} The key.\n * @param amount {Number} The amount to increment by.\n */\n increment: function increment(attr, amount) {\n if (_.isUndefined(amount) || _.isNull(amount)) {\n amount = 1;\n }\n\n return this.set(attr, new AV.Op.Increment(amount));\n },\n\n /**\n * Atomically add an object to the end of the array associated with a given\n * key.\n * @param key {String} The key.\n * @param item {} The item to add.\n */\n add: function add(attr, item) {\n return this.set(attr, new AV.Op.Add(ensureArray(item)));\n },\n\n /**\n * Atomically add an object to the array associated with a given key, only\n * if it is not already present in the array. The position of the insert is\n * not guaranteed.\n *\n * @param key {String} The key.\n * @param item {} The object to add.\n */\n addUnique: function addUnique(attr, item) {\n return this.set(attr, new AV.Op.AddUnique(ensureArray(item)));\n },\n\n /**\n * Atomically remove all instances of an object from the array associated\n * with a given key.\n *\n * @param key {String} The key.\n * @param item {} The object to remove.\n */\n remove: function remove(attr, item) {\n return this.set(attr, new AV.Op.Remove(ensureArray(item)));\n },\n\n /**\n * Atomically apply a \"bit and\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitAnd: function bitAnd(attr, value) {\n return this.set(attr, new AV.Op.BitAnd(value));\n },\n\n /**\n * Atomically apply a \"bit or\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitOr: function bitOr(attr, value) {\n return this.set(attr, new AV.Op.BitOr(value));\n },\n\n /**\n * Atomically apply a \"bit xor\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitXor: function bitXor(attr, value) {\n return this.set(attr, new AV.Op.BitXor(value));\n },\n\n /**\n * Returns an instance of a subclass of AV.Op describing what kind of\n * modification has been performed on this field since the last time it was\n * saved. For example, after calling object.increment(\"x\"), calling\n * object.op(\"x\") would return an instance of AV.Op.Increment.\n *\n * @param key {String} The key.\n * @returns {AV.Op} The operation, or undefined if none.\n */\n op: function op(attr) {\n return _.last(this._opSetQueue)[attr];\n },\n\n /**\n * Clear all attributes on the model, firing \"change\"
unless\n * you choose to silence it.\n */\n clear: function clear(options) {\n options = options || {};\n options.unset = true;\n\n var keysToClear = _.extend(this.attributes, this._operations);\n\n return this.set(keysToClear, options);\n },\n\n /**\n * Clears any (or specific) changes to the model made since the last save.\n * @param {string|string[]} [keys] specify keys to revert.\n */\n revert: function revert(keys) {\n var lastOp = _.last(this._opSetQueue);\n\n var _keys = ensureArray(keys || (0, _keys2.default)(_).call(_, lastOp));\n\n _keys.forEach(function (key) {\n delete lastOp[key];\n });\n\n this._rebuildAllEstimatedData();\n\n return this;\n },\n\n /**\n * Returns a JSON-encoded set of operations to be sent with the next save\n * request.\n * @private\n */\n _getSaveJSON: function _getSaveJSON() {\n var json = _.clone(_.first(this._opSetQueue));\n\n AV._objectEach(json, function (op, key) {\n json[key] = op.toJSON();\n });\n\n return json;\n },\n\n /**\n * Returns true if this object can be serialized for saving.\n * @private\n */\n _canBeSerialized: function _canBeSerialized() {\n return AV.Object._canBeSerializedAsValue(this.attributes);\n },\n\n /**\n * Fetch the model from the server. If the server's representation of the\n * model differs from its current attributes, they will be overriden,\n * triggering a \"change\"
event.\n * @param {Object} fetchOptions Optional options to set 'keys',\n * 'include' and 'includeACL' option.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the fetch\n * completes.\n */\n fetch: function fetch() {\n var fetchOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var options = arguments.length > 1 ? arguments[1] : undefined;\n\n if (!this.id) {\n throw new Error('Cannot fetch unsaved object');\n }\n\n var self = this;\n\n var request = _request('classes', this.className, this.id, 'GET', transformFetchOptions(fetchOptions), options);\n\n return request.then(function (response) {\n var fetchedAttrs = self.parse(response);\n\n self._cleanupUnsetKeys(fetchedAttrs, (0, _keys2.default)(fetchOptions) ? ensureArray((0, _keys2.default)(fetchOptions)).join(',').split(',') : undefined);\n\n self._finishFetch(fetchedAttrs, true);\n\n return self;\n });\n },\n _cleanupUnsetKeys: function _cleanupUnsetKeys(fetchedAttrs) {\n var _this2 = this;\n\n var fetchedKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (0, _keys2.default)(_).call(_, this._serverData);\n\n _.forEach(fetchedKeys, function (key) {\n if (fetchedAttrs[key] === undefined) delete _this2._serverData[key];\n });\n },\n\n /**\n * Set a hash of model attributes, and save the model to the server.\n * updatedAt will be updated when the request returns.\n * You can either call it as:\n * object.save();\n * or
\n * object.save(null, options);\n * or
\n * object.save(attrs, options);\n * or
\n * object.save(key, value, options);\n *\n * @example\n * gameTurn.save({\n * player: \"Jake Cutter\",\n * diceRoll: 2\n * }).then(function(gameTurnAgain) {\n * // The save was successful.\n * }, function(error) {\n * // The save failed. Error is an instance of AVError.\n * });\n *\n * @param {AuthOptions} options AuthOptions plus:\n * @param {Boolean} options.fetchWhenSave fetch and update object after save succeeded\n * @param {AV.Query} options.query Save object only when it matches the query\n * @return {Promise} A promise that is fulfilled when the save\n * completes.\n * @see AVError\n */\n save: function save(arg1, arg2, arg3) {\n var attrs, current, options;\n\n if (_.isObject(arg1) || isNullOrUndefined(arg1)) {\n attrs = arg1;\n options = arg2;\n } else {\n attrs = {};\n attrs[arg1] = arg2;\n options = arg3;\n }\n\n options = _.clone(options) || {};\n\n if (options.wait) {\n current = _.clone(this.attributes);\n }\n\n var setOptions = _.clone(options) || {};\n\n if (setOptions.wait) {\n setOptions.silent = true;\n }\n\n if (attrs) {\n this.set(attrs, setOptions);\n }\n\n var model = this;\n var unsavedChildren = [];\n var unsavedFiles = [];\n\n AV.Object._findUnsavedChildren(model, unsavedChildren, unsavedFiles);\n\n if (unsavedChildren.length + unsavedFiles.length > 1) {\n return AV.Object._deepSaveAsync(this, model, options);\n }\n\n this._startSave();\n\n this._saving = (this._saving || 0) + 1;\n this._allPreviousSaves = this._allPreviousSaves || _promise.default.resolve();\n this._allPreviousSaves = this._allPreviousSaves.catch(function (e) {}).then(function () {\n var method = model.id ? 'PUT' : 'POST';\n\n var json = model._getSaveJSON();\n\n var query = {};\n\n if (model._fetchWhenSave || options.fetchWhenSave) {\n query['new'] = 'true';\n } // user login option\n\n\n if (options._failOnNotExist) {\n query.failOnNotExist = 'true';\n }\n\n if (options.query) {\n var queryParams;\n\n if (typeof options.query._getParams === 'function') {\n queryParams = options.query._getParams();\n\n if (queryParams) {\n query.where = queryParams.where;\n }\n }\n\n if (!query.where) {\n var error = new Error('options.query is not an AV.Query');\n throw error;\n }\n }\n\n _.extend(json, model._flags);\n\n var route = 'classes';\n var className = model.className;\n\n if (model.className === '_User' && !model.id) {\n // Special-case user sign-up.\n route = 'users';\n className = null;\n } //hook makeRequest in options.\n\n\n var makeRequest = options._makeRequest || _request;\n var requestPromise = makeRequest(route, className, model.id, method, json, options, query);\n requestPromise = requestPromise.then(function (resp) {\n var serverAttrs = model.parse(resp);\n\n if (options.wait) {\n serverAttrs = _.extend(attrs || {}, serverAttrs);\n }\n\n model._finishSave(serverAttrs);\n\n if (options.wait) {\n model.set(current, setOptions);\n }\n\n return model;\n }, function (error) {\n model._cancelSave();\n\n throw error;\n });\n return requestPromise;\n });\n return this._allPreviousSaves;\n },\n\n /**\n * Destroy this model on the server if it was already persisted.\n * Optimistically removes the model from its collection, if it has one.\n * @param {AuthOptions} options AuthOptions plus:\n * @param {Boolean} [options.wait] wait for the server to respond\n * before removal.\n *\n * @return {Promise} A promise that is fulfilled when the destroy\n * completes.\n */\n destroy: function destroy(options) {\n options = options || {};\n var model = this;\n\n var triggerDestroy = function triggerDestroy() {\n model.trigger('destroy', model, model.collection, options);\n };\n\n if (!this.id) {\n return triggerDestroy();\n }\n\n if (!options.wait) {\n triggerDestroy();\n }\n\n var request = _request('classes', this.className, this.id, 'DELETE', this._flags, options);\n\n return request.then(function () {\n if (options.wait) {\n triggerDestroy();\n }\n\n return model;\n });\n },\n\n /**\n * Converts a response into the hash of attributes to be set on the model.\n * @ignore\n */\n parse: function parse(resp) {\n var output = _.clone(resp);\n\n ['createdAt', 'updatedAt'].forEach(function (key) {\n if (output[key]) {\n output[key] = AV._parseDate(output[key]);\n }\n });\n\n if (output.createdAt && !output.updatedAt) {\n output.updatedAt = output.createdAt;\n }\n\n return output;\n },\n\n /**\n * Creates a new model with identical attributes to this one.\n * @return {AV.Object}\n */\n clone: function clone() {\n return new this.constructor(this.attributes);\n },\n\n /**\n * Returns true if this object has never been saved to AV.\n * @return {Boolean}\n */\n isNew: function isNew() {\n return !this.id;\n },\n\n /**\n * Call this method to manually fire a `\"change\"` event for this model and\n * a `\"change:attribute\"` event for each changed attribute.\n * Calling this will cause all objects observing the model to update.\n */\n change: function change(options) {\n options = options || {};\n var changing = this._changing;\n this._changing = true; // Silent changes become pending changes.\n\n var self = this;\n\n AV._objectEach(this._silent, function (attr) {\n self._pending[attr] = true;\n }); // Silent changes are triggered.\n\n\n var changes = _.extend({}, options.changes, this._silent);\n\n this._silent = {};\n\n AV._objectEach(changes, function (unused_value, attr) {\n self.trigger('change:' + attr, self, self.get(attr), options);\n });\n\n if (changing) {\n return this;\n } // This is to get around lint not letting us make a function in a loop.\n\n\n var deleteChanged = function deleteChanged(value, attr) {\n if (!self._pending[attr] && !self._silent[attr]) {\n delete self.changed[attr];\n }\n }; // Continue firing `\"change\"` events while there are pending changes.\n\n\n while (!_.isEmpty(this._pending)) {\n this._pending = {};\n this.trigger('change', this, options); // Pending and silent changes still remain.\n\n AV._objectEach(this.changed, deleteChanged);\n\n self._previousAttributes = _.clone(this.attributes);\n }\n\n this._changing = false;\n return this;\n },\n\n /**\n * Gets the previous value of an attribute, recorded at the time the last\n *
\"change\"
event was fired.\n * @param {String} attr Name of the attribute to get.\n */\n previous: function previous(attr) {\n if (!arguments.length || !this._previousAttributes) {\n return null;\n }\n\n return this._previousAttributes[attr];\n },\n\n /**\n * Gets all of the attributes of the model at the time of the previous\n * \"change\"
event.\n * @return {Object}\n */\n previousAttributes: function previousAttributes() {\n return _.clone(this._previousAttributes);\n },\n\n /**\n * Checks if the model is currently in a valid state. It's only possible to\n * get into an *invalid* state if you're using silent changes.\n * @return {Boolean}\n */\n isValid: function isValid() {\n try {\n this.validate(this.attributes);\n } catch (error) {\n return false;\n }\n\n return true;\n },\n\n /**\n * You should not call this function directly unless you subclass\n * AV.Object
, in which case you can override this method\n * to provide additional validation on set
and\n * save
. Your implementation should throw an Error if\n * the attrs is invalid\n *\n * @param {Object} attrs The current data to validate.\n * @see AV.Object#set\n */\n validate: function validate(attrs) {\n if (_.has(attrs, 'ACL') && !(attrs.ACL instanceof AV.ACL)) {\n throw new AVError(AVError.OTHER_CAUSE, 'ACL must be a AV.ACL.');\n }\n },\n\n /**\n * Run validation against a set of incoming attributes, returning `true`\n * if all is well. If a specific `error` callback has been passed,\n * call that instead of firing the general `\"error\"` event.\n * @private\n */\n _validate: function _validate(attrs, options) {\n if (options.silent || !this.validate) {\n return;\n }\n\n attrs = _.extend({}, this.attributes, attrs);\n this.validate(attrs);\n },\n\n /**\n * Returns the ACL for this object.\n * @returns {AV.ACL} An instance of AV.ACL.\n * @see AV.Object#get\n */\n getACL: function getACL() {\n return this.get('ACL');\n },\n\n /**\n * Sets the ACL to be used for this object.\n * @param {AV.ACL} acl An instance of AV.ACL.\n * @param {Object} options Optional Backbone-like options object to be\n * passed in to set.\n * @return {AV.Object} self\n * @see AV.Object#set\n */\n setACL: function setACL(acl, options) {\n return this.set('ACL', acl, options);\n },\n disableBeforeHook: function disableBeforeHook() {\n this.ignoreHook('beforeSave');\n this.ignoreHook('beforeUpdate');\n this.ignoreHook('beforeDelete');\n },\n disableAfterHook: function disableAfterHook() {\n this.ignoreHook('afterSave');\n this.ignoreHook('afterUpdate');\n this.ignoreHook('afterDelete');\n },\n ignoreHook: function ignoreHook(hookName) {\n if (!_.contains(['beforeSave', 'afterSave', 'beforeUpdate', 'afterUpdate', 'beforeDelete', 'afterDelete'], hookName)) {\n throw new Error('Unsupported hookName: ' + hookName);\n }\n\n if (!AV.hookKey) {\n throw new Error('ignoreHook required hookKey');\n }\n\n if (!this._flags.__ignore_hooks) {\n this._flags.__ignore_hooks = [];\n }\n\n this._flags.__ignore_hooks.push(hookName);\n }\n });\n /**\n * Creates an instance of a subclass of AV.Object for the give classname\n * and id.\n * @param {String|Function} class the className or a subclass of AV.Object.\n * @param {String} id The object id of this model.\n * @return {AV.Object} A new subclass instance of AV.Object.\n */\n\n\n AV.Object.createWithoutData = function (klass, id, hasData) {\n var _klass;\n\n if (_.isString(klass)) {\n _klass = AV.Object._getSubclass(klass);\n } else if (klass.prototype && klass.prototype instanceof AV.Object) {\n _klass = klass;\n } else {\n throw new Error('class must be a string or a subclass of AV.Object.');\n }\n\n if (!id) {\n throw new TypeError('The objectId must be provided');\n }\n\n var object = new _klass();\n object.id = id;\n object._hasData = hasData;\n return object;\n };\n /**\n * Delete objects in batch.\n * @param {AV.Object[]} objects The AV.Object
array to be deleted.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the save\n * completes.\n */\n\n\n AV.Object.destroyAll = function (objects) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!objects || objects.length === 0) {\n return _promise.default.resolve();\n }\n\n var objectsByClassNameAndFlags = _.groupBy(objects, function (object) {\n return (0, _stringify.default)({\n className: object.className,\n flags: object._flags\n });\n });\n\n var body = {\n requests: (0, _map.default)(_).call(_, objectsByClassNameAndFlags, function (objects) {\n var _context3;\n\n var ids = (0, _map.default)(_).call(_, objects, 'id').join(',');\n return {\n method: 'DELETE',\n path: (0, _concat.default)(_context3 = \"/1.1/classes/\".concat(objects[0].className, \"/\")).call(_context3, ids),\n body: objects[0]._flags\n };\n })\n };\n return _request('batch', null, null, 'POST', body, options).then(function (response) {\n var firstError = (0, _find.default)(_).call(_, response, function (result) {\n return !result.success;\n });\n if (firstError) throw new AVError(firstError.error.code, firstError.error.error);\n return undefined;\n });\n };\n /**\n * Returns the appropriate subclass for making new instances of the given\n * className string.\n * @private\n */\n\n\n AV.Object._getSubclass = function (className) {\n if (!_.isString(className)) {\n throw new Error('AV.Object._getSubclass requires a string argument.');\n }\n\n var ObjectClass = AV.Object._classMap[className];\n\n if (!ObjectClass) {\n ObjectClass = AV.Object.extend(className);\n AV.Object._classMap[className] = ObjectClass;\n }\n\n return ObjectClass;\n };\n /**\n * Creates an instance of a subclass of AV.Object for the given classname.\n * @private\n */\n\n\n AV.Object._create = function (className, attributes, options) {\n var ObjectClass = AV.Object._getSubclass(className);\n\n return new ObjectClass(attributes, options);\n }; // Set up a map of className to class so that we can create new instances of\n // AV Objects from JSON automatically.\n\n\n AV.Object._classMap = {};\n AV.Object._extend = AV._extend;\n /**\n * Creates a new model with defined attributes,\n * It's the same with\n * \n * new AV.Object(attributes, options);\n *\n * @param {Object} attributes The initial set of data to store in the object.\n * @param {Object} options A set of Backbone-like options for creating the\n * object. The only option currently supported is \"collection\".\n * @return {AV.Object}\n * @since v0.4.4\n * @see AV.Object\n * @see AV.Object.extend\n */\n\n AV.Object['new'] = function (attributes, options) {\n return new AV.Object(attributes, options);\n };\n /**\n * Creates a new subclass of AV.Object for the given AV class name.\n *\n *
Every extension of a AV class will inherit from the most recent\n * previous extension of that class. When a AV.Object is automatically\n * created by parsing JSON, it will use the most recent extension of that\n * class.
\n *\n * @example\n * var MyClass = AV.Object.extend(\"MyClass\", {\n * // Instance properties\n * }, {\n * // Class properties\n * });\n *\n * @param {String} className The name of the AV class backing this model.\n * @param {Object} protoProps Instance properties to add to instances of the\n * class returned from this method.\n * @param {Object} classProps Class properties to add the class returned from\n * this method.\n * @return {Class} A new subclass of AV.Object.\n */\n\n\n AV.Object.extend = function (className, protoProps, classProps) {\n // Handle the case with only two args.\n if (!_.isString(className)) {\n if (className && _.has(className, 'className')) {\n return AV.Object.extend(className.className, className, protoProps);\n } else {\n throw new Error(\"AV.Object.extend's first argument should be the className.\");\n }\n } // If someone tries to subclass \"User\", coerce it to the right type.\n\n\n if (className === 'User') {\n className = '_User';\n }\n\n var NewClassObject = null;\n\n if (_.has(AV.Object._classMap, className)) {\n var OldClassObject = AV.Object._classMap[className]; // This new subclass has been told to extend both from \"this\" and from\n // OldClassObject. This is multiple inheritance, which isn't supported.\n // For now, let's just pick one.\n\n if (protoProps || classProps) {\n NewClassObject = OldClassObject._extend(protoProps, classProps);\n } else {\n return OldClassObject;\n }\n } else {\n protoProps = protoProps || {};\n protoProps._className = className;\n NewClassObject = this._extend(protoProps, classProps);\n } // Extending a subclass should reuse the classname automatically.\n\n\n NewClassObject.extend = function (arg0) {\n var _context4;\n\n if (_.isString(arg0) || arg0 && _.has(arg0, 'className')) {\n return AV.Object.extend.apply(NewClassObject, arguments);\n }\n\n var newArguments = (0, _concat.default)(_context4 = [className]).call(_context4, _.toArray(arguments));\n return AV.Object.extend.apply(NewClassObject, newArguments);\n }; // Add the query property descriptor.\n\n\n (0, _defineProperty.default)(NewClassObject, 'query', (0, _getOwnPropertyDescriptor.default)(AV.Object, 'query'));\n\n NewClassObject['new'] = function (attributes, options) {\n return new NewClassObject(attributes, options);\n };\n\n AV.Object._classMap[className] = NewClassObject;\n return NewClassObject;\n }; // ES6 class syntax support\n\n\n (0, _defineProperty.default)(AV.Object.prototype, 'className', {\n get: function get() {\n var className = this._className || this.constructor._LCClassName || this.constructor.name; // If someone tries to subclass \"User\", coerce it to the right type.\n\n if (className === 'User') {\n return '_User';\n }\n\n return className;\n }\n });\n /**\n * Register a class.\n * If a subclass ofAV.Object
is defined with your own implement\n * rather then AV.Object.extend
, the subclass must be registered.\n * @param {Function} klass A subclass of AV.Object
\n * @param {String} [name] Specify the name of the class. Useful when the class might be uglified.\n * @example\n * class Person extend AV.Object {}\n * AV.Object.register(Person);\n */\n\n AV.Object.register = function (klass, name) {\n if (!(klass.prototype instanceof AV.Object)) {\n throw new Error('registered class is not a subclass of AV.Object');\n }\n\n var className = name || klass.name;\n\n if (!className.length) {\n throw new Error('registered class must be named');\n }\n\n if (name) {\n klass._LCClassName = name;\n }\n\n AV.Object._classMap[className] = klass;\n };\n /**\n * Get a new Query of the current class\n * @name query\n * @memberof AV.Object\n * @type AV.Query\n * @readonly\n * @since v3.1.0\n * @example\n * const Post = AV.Object.extend('Post');\n * Post.query.equalTo('author', 'leancloud').find().then();\n */\n\n\n (0, _defineProperty.default)(AV.Object, 'query', {\n get: function get() {\n return new AV.Query(this.prototype.className);\n }\n });\n\n AV.Object._findUnsavedChildren = function (objects, children, files) {\n AV._traverse(objects, function (object) {\n if (object instanceof AV.Object) {\n if (object.dirty()) {\n children.push(object);\n }\n\n return;\n }\n\n if (object instanceof AV.File) {\n if (!object.id) {\n files.push(object);\n }\n\n return;\n }\n });\n };\n\n AV.Object._canBeSerializedAsValue = function (object) {\n var canBeSerializedAsValue = true;\n\n if (object instanceof AV.Object || object instanceof AV.File) {\n canBeSerializedAsValue = !!object.id;\n } else if (_.isArray(object)) {\n AV._arrayEach(object, function (child) {\n if (!AV.Object._canBeSerializedAsValue(child)) {\n canBeSerializedAsValue = false;\n }\n });\n } else if (_.isObject(object)) {\n AV._objectEach(object, function (child) {\n if (!AV.Object._canBeSerializedAsValue(child)) {\n canBeSerializedAsValue = false;\n }\n });\n }\n\n return canBeSerializedAsValue;\n };\n\n AV.Object._deepSaveAsync = function (object, model, options) {\n var unsavedChildren = [];\n var unsavedFiles = [];\n\n AV.Object._findUnsavedChildren(object, unsavedChildren, unsavedFiles);\n\n unsavedFiles = _.uniq(unsavedFiles);\n\n var promise = _promise.default.resolve();\n\n _.each(unsavedFiles, function (file) {\n promise = promise.then(function () {\n return file.save();\n });\n });\n\n var objects = _.uniq(unsavedChildren);\n\n var remaining = _.uniq(objects);\n\n return promise.then(function () {\n return continueWhile(function () {\n return remaining.length > 0;\n }, function () {\n // Gather up all the objects that can be saved in this batch.\n var batch = [];\n var newRemaining = [];\n\n AV._arrayEach(remaining, function (object) {\n if (object._canBeSerialized()) {\n batch.push(object);\n } else {\n newRemaining.push(object);\n }\n });\n\n remaining = newRemaining; // If we can't save any objects, there must be a circular reference.\n\n if (batch.length === 0) {\n return _promise.default.reject(new AVError(AVError.OTHER_CAUSE, 'Tried to save a batch with a cycle.'));\n } // Reserve a spot in every object's save queue.\n\n\n var readyToStart = _promise.default.resolve((0, _map.default)(_).call(_, batch, function (object) {\n return object._allPreviousSaves || _promise.default.resolve();\n })); // Save a single batch, whether previous saves succeeded or failed.\n\n\n var bathSavePromise = readyToStart.then(function () {\n return _request('batch', null, null, 'POST', {\n requests: (0, _map.default)(_).call(_, batch, function (object) {\n var method = object.id ? 'PUT' : 'POST';\n\n var json = object._getSaveJSON();\n\n _.extend(json, object._flags);\n\n var route = 'classes';\n var className = object.className;\n var path = \"/\".concat(route, \"/\").concat(className);\n\n if (object.className === '_User' && !object.id) {\n // Special-case user sign-up.\n path = '/users';\n }\n\n var path = \"/1.1\".concat(path);\n\n if (object.id) {\n path = path + '/' + object.id;\n }\n\n object._startSave();\n\n return {\n method: method,\n path: path,\n body: json,\n params: options && options.fetchWhenSave ? {\n fetchWhenSave: true\n } : undefined\n };\n })\n }, options).then(function (response) {\n var results = (0, _map.default)(_).call(_, batch, function (object, i) {\n if (response[i].success) {\n object._finishSave(object.parse(response[i].success));\n\n return object;\n }\n\n object._cancelSave();\n\n return new AVError(response[i].error.code, response[i].error.error);\n });\n return handleBatchResults(results);\n });\n });\n\n AV._arrayEach(batch, function (object) {\n object._allPreviousSaves = bathSavePromise;\n });\n\n return bathSavePromise;\n });\n }).then(function () {\n return object;\n });\n };\n};\n\n/***/ }),\n/* 501 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar arrayWithHoles = __webpack_require__(502);\n\nvar iterableToArrayLimit = __webpack_require__(510);\n\nvar unsupportedIterableToArray = __webpack_require__(511);\n\nvar nonIterableRest = __webpack_require__(521);\n\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}\n\nmodule.exports = _slicedToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n/***/ }),\n/* 502 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar _Array$isArray = __webpack_require__(503);\n\nfunction _arrayWithHoles(arr) {\n if (_Array$isArray(arr)) return arr;\n}\n\nmodule.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n/***/ }),\n/* 503 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(504);\n\n/***/ }),\n/* 504 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(505);\n\n\n/***/ }),\n/* 505 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(506);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 506 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(507);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 507 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(508);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 508 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(509);\nvar path = __webpack_require__(13);\n\nmodule.exports = path.Array.isArray;\n\n\n/***/ }),\n/* 509 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $ = __webpack_require__(0);\nvar isArray = __webpack_require__(80);\n\n// `Array.isArray` method\n// https://tc39.es/ecma262/#sec-array.isarray\n$({ target: 'Array', stat: true }, {\n isArray: isArray\n});\n\n\n/***/ }),\n/* 510 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar _Symbol = __webpack_require__(225);\n\nvar _getIteratorMethod = __webpack_require__(231);\n\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof _Symbol !== \"undefined\" && _getIteratorMethod(arr) || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nmodule.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n/***/ }),\n/* 511 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar _sliceInstanceProperty = __webpack_require__(512);\n\nvar _Array$from = __webpack_require__(516);\n\nvar arrayLikeToArray = __webpack_require__(520);\n\nfunction _unsupportedIterableToArray(o, minLen) {\n var _context;\n\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n\n var n = _sliceInstanceProperty(_context = Object.prototype.toString.call(o)).call(_context, 8, -1);\n\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return _Array$from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}\n\nmodule.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n/***/ }),\n/* 512 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(513);\n\n/***/ }),\n/* 513 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(514);\n\n\n/***/ }),\n/* 514 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(515);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 515 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(222);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 516 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(517);\n\n/***/ }),\n/* 517 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(518);\n\n\n/***/ }),\n/* 518 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(519);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 519 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(230);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 520 */\n/***/ (function(module, exports) {\n\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}\n\nmodule.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n/***/ }),\n/* 521 */\n/***/ (function(module, exports) {\n\nfunction _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nmodule.exports = _nonIterableRest, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n/***/ }),\n/* 522 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(523);\n\n/***/ }),\n/* 523 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar parent = __webpack_require__(524);\n\nmodule.exports = parent;\n\n\n/***/ }),\n/* 524 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(525);\nvar path = __webpack_require__(13);\n\nvar Object = path.Object;\n\nvar getOwnPropertyDescriptor = module.exports = function getOwnPropertyDescriptor(it, key) {\n return Object.getOwnPropertyDescriptor(it, key);\n};\n\nif (Object.getOwnPropertyDescriptor.sham) getOwnPropertyDescriptor.sham = true;\n\n\n/***/ }),\n/* 525 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $ = __webpack_require__(0);\nvar fails = __webpack_require__(4);\nvar toIndexedObject = __webpack_require__(33);\nvar nativeGetOwnPropertyDescriptor = __webpack_require__(64).f;\nvar DESCRIPTORS = __webpack_require__(19);\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeGetOwnPropertyDescriptor(1); });\nvar FORCED = !DESCRIPTORS || FAILS_ON_PRIMITIVES;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\n$({ target: 'Object', stat: true, forced: FORCED, sham: !DESCRIPTORS }, {\n getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) {\n return nativeGetOwnPropertyDescriptor(toIndexedObject(it), key);\n }\n});\n\n\n/***/ }),\n/* 526 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _ = __webpack_require__(1);\n\nvar AVError = __webpack_require__(40);\n\nmodule.exports = function (AV) {\n AV.Role = AV.Object.extend('_Role',\n /** @lends AV.Role.prototype */\n {\n // Instance Methods\n\n /**\n * Represents a Role on the AV server. Roles represent groupings of\n * Users for the purposes of granting permissions (e.g. specifying an ACL\n * for an Object). Roles are specified by their sets of child users and\n * child roles, all of which are granted any permissions that the parent\n * role has.\n *\n * Roles must have a name (which cannot be changed after creation of the\n * role), and must specify an ACL.
\n * An AV.Role is a local representation of a role persisted to the AV\n * cloud.\n * @class AV.Role\n * @param {String} name The name of the Role to create.\n * @param {AV.ACL} acl The ACL for this role.\n */\n constructor: function constructor(name, acl) {\n if (_.isString(name)) {\n AV.Object.prototype.constructor.call(this, null, null);\n this.setName(name);\n } else {\n AV.Object.prototype.constructor.call(this, name, acl);\n }\n\n if (acl) {\n if (!(acl instanceof AV.ACL)) {\n throw new TypeError('acl must be an instance of AV.ACL');\n } else {\n this.setACL(acl);\n }\n }\n },\n\n /**\n * Gets the name of the role. You can alternatively call role.get(\"name\")\n *\n * @return {String} the name of the role.\n */\n getName: function getName() {\n return this.get('name');\n },\n\n /**\n * Sets the name for a role. This value must be set before the role has\n * been saved to the server, and cannot be set once the role has been\n * saved.\n *\n *\n * A role's name can only contain alphanumeric characters, _, -, and\n * spaces.\n *
\n *\n *This is equivalent to calling role.set(\"name\", name)
\n *\n * @param {String} name The name of the role.\n */\n setName: function setName(name, options) {\n return this.set('name', name, options);\n },\n\n /**\n * Gets the AV.Relation for the AV.Users that are direct\n * children of this role. These users are granted any privileges that this\n * role has been granted (e.g. read or write access through ACLs). You can\n * add or remove users from the role through this relation.\n *\n *This is equivalent to calling role.relation(\"users\")
\n *\n * @return {AV.Relation} the relation for the users belonging to this\n * role.\n */\n getUsers: function getUsers() {\n return this.relation('users');\n },\n\n /**\n * Gets the AV.Relation for the AV.Roles that are direct\n * children of this role. These roles' users are granted any privileges that\n * this role has been granted (e.g. read or write access through ACLs). You\n * can add or remove child roles from this role through this relation.\n *\n *This is equivalent to calling role.relation(\"roles\")
\n *\n * @return {AV.Relation} the relation for the roles belonging to this\n * role.\n */\n getRoles: function getRoles() {\n return this.relation('roles');\n },\n\n /**\n * @ignore\n */\n validate: function validate(attrs, options) {\n if ('name' in attrs && attrs.name !== this.getName()) {\n var newName = attrs.name;\n\n if (this.id && this.id !== attrs.objectId) {\n // Check to see if the objectId being set matches this.id.\n // This happens during a fetch -- the id is set before calling fetch.\n // Let the name be set in this case.\n return new AVError(AVError.OTHER_CAUSE, \"A role's name can only be set before it has been saved.\");\n }\n\n if (!_.isString(newName)) {\n return new AVError(AVError.OTHER_CAUSE, \"A role's name must be a String.\");\n }\n\n if (!/^[0-9a-zA-Z\\-_ ]+$/.test(newName)) {\n return new AVError(AVError.OTHER_CAUSE, \"A role's name can only contain alphanumeric characters, _,\" + ' -, and spaces.');\n }\n }\n\n if (AV.Object.prototype.validate) {\n return AV.Object.prototype.validate.call(this, attrs, options);\n }\n\n return false;\n }\n });\n};\n\n/***/ }),\n/* 527 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _interopRequireDefault = __webpack_require__(2);\n\nvar _defineProperty2 = _interopRequireDefault(__webpack_require__(528));\n\nvar _promise = _interopRequireDefault(__webpack_require__(10));\n\nvar _map = _interopRequireDefault(__webpack_require__(39));\n\nvar _find = _interopRequireDefault(__webpack_require__(104));\n\nvar _stringify = _interopRequireDefault(__webpack_require__(34));\n\nvar _ = __webpack_require__(1);\n\nvar uuid = __webpack_require__(214);\n\nvar AVError = __webpack_require__(40);\n\nvar _require = __webpack_require__(25),\n AVRequest = _require._request,\n request = _require.request;\n\nvar _require2 = __webpack_require__(61),\n getAdapter = _require2.getAdapter;\n\nvar PLATFORM_ANONYMOUS = 'anonymous';\nvar PLATFORM_QQAPP = 'lc_qqapp';\n\nvar mergeUnionDataIntoAuthData = function mergeUnionDataIntoAuthData() {\n var defaultUnionIdPlatform = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'weixin';\n return function (authData, unionId) {\n var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},\n _ref$unionIdPlatform = _ref.unionIdPlatform,\n unionIdPlatform = _ref$unionIdPlatform === void 0 ? defaultUnionIdPlatform : _ref$unionIdPlatform,\n _ref$asMainAccount = _ref.asMainAccount,\n asMainAccount = _ref$asMainAccount === void 0 ? false : _ref$asMainAccount;\n\n if (typeof unionId !== 'string') throw new AVError(AVError.OTHER_CAUSE, 'unionId is not a string');\n if (typeof unionIdPlatform !== 'string') throw new AVError(AVError.OTHER_CAUSE, 'unionIdPlatform is not a string');\n return _.extend({}, authData, {\n platform: unionIdPlatform,\n unionid: unionId,\n main_account: Boolean(asMainAccount)\n });\n };\n};\n\nmodule.exports = function (AV) {\n /**\n * @class\n *\n *An AV.User object is a local representation of a user persisted to the\n * LeanCloud server. This class is a subclass of an AV.Object, and retains the\n * same functionality of an AV.Object, but also extends it with various\n * user specific methods, like authentication, signing up, and validation of\n * uniqueness.
\n */\n AV.User = AV.Object.extend('_User',\n /** @lends AV.User.prototype */\n {\n // Instance Variables\n _isCurrentUser: false,\n // Instance Methods\n\n /**\n * Internal method to handle special fields in a _User response.\n * @private\n */\n _mergeMagicFields: function _mergeMagicFields(attrs) {\n if (attrs.sessionToken) {\n this._sessionToken = attrs.sessionToken;\n delete attrs.sessionToken;\n }\n\n return AV.User.__super__._mergeMagicFields.call(this, attrs);\n },\n\n /**\n * Removes null values from authData (which exist temporarily for\n * unlinking)\n * @private\n */\n _cleanupAuthData: function _cleanupAuthData() {\n if (!this.isCurrent()) {\n return;\n }\n\n var authData = this.get('authData');\n\n if (!authData) {\n return;\n }\n\n AV._objectEach(this.get('authData'), function (value, key) {\n if (!authData[key]) {\n delete authData[key];\n }\n });\n },\n\n /**\n * Synchronizes authData for all providers.\n * @private\n */\n _synchronizeAllAuthData: function _synchronizeAllAuthData() {\n var authData = this.get('authData');\n\n if (!authData) {\n return;\n }\n\n var self = this;\n\n AV._objectEach(this.get('authData'), function (value, key) {\n self._synchronizeAuthData(key);\n });\n },\n\n /**\n * Synchronizes auth data for a provider (e.g. puts the access token in the\n * right place to be used by the Facebook SDK).\n * @private\n */\n _synchronizeAuthData: function _synchronizeAuthData(provider) {\n if (!this.isCurrent()) {\n return;\n }\n\n var authType;\n\n if (_.isString(provider)) {\n authType = provider;\n provider = AV.User._authProviders[authType];\n } else {\n authType = provider.getAuthType();\n }\n\n var authData = this.get('authData');\n\n if (!authData || !provider) {\n return;\n }\n\n var success = provider.restoreAuthentication(authData[authType]);\n\n if (!success) {\n this.dissociateAuthData(provider);\n }\n },\n _handleSaveResult: function _handleSaveResult(makeCurrent) {\n // Clean up and synchronize the authData object, removing any unset values\n if (makeCurrent && !AV._config.disableCurrentUser) {\n this._isCurrentUser = true;\n }\n\n this._cleanupAuthData();\n\n this._synchronizeAllAuthData(); // Don't keep the password around.\n\n\n delete this._serverData.password;\n\n this._rebuildEstimatedDataForKey('password');\n\n this._refreshCache();\n\n if ((makeCurrent || this.isCurrent()) && !AV._config.disableCurrentUser) {\n // Some old version of leanengine-node-sdk will overwrite\n // AV.User._saveCurrentUser which returns no Promise.\n // So we need a Promise wrapper.\n return _promise.default.resolve(AV.User._saveCurrentUser(this));\n } else {\n return _promise.default.resolve();\n }\n },\n\n /**\n * Unlike in the Android/iOS SDKs, logInWith is unnecessary, since you can\n * call linkWith on the user (even if it doesn't exist yet on the server).\n * @private\n */\n _linkWith: function _linkWith(provider, data) {\n var _this = this;\n\n var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},\n _ref2$failOnNotExist = _ref2.failOnNotExist,\n failOnNotExist = _ref2$failOnNotExist === void 0 ? false : _ref2$failOnNotExist,\n useMasterKey = _ref2.useMasterKey,\n sessionToken = _ref2.sessionToken,\n user = _ref2.user;\n\n var authType;\n\n if (_.isString(provider)) {\n authType = provider;\n provider = AV.User._authProviders[provider];\n } else {\n authType = provider.getAuthType();\n }\n\n if (data) {\n return this.save({\n authData: (0, _defineProperty2.default)({}, authType, data)\n }, {\n useMasterKey: useMasterKey,\n sessionToken: sessionToken,\n user: user,\n fetchWhenSave: !!this.get('authData'),\n _failOnNotExist: failOnNotExist\n }).then(function (model) {\n return model._handleSaveResult(true).then(function () {\n return model;\n });\n });\n } else {\n return provider.authenticate().then(function (result) {\n return _this._linkWith(provider, result);\n });\n }\n },\n\n /**\n * Associate the user with a third party authData.\n * @since 3.3.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @return {Promisecurrent
.\n *\n * A username and password must be set before calling signUp.
\n *\n * @param {Object} attrs Extra fields to set on the new user, or null.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the signup\n * finishes.\n * @see AV.User.signUp\n */\n signUp: function signUp(attrs, options) {\n var error;\n var username = attrs && attrs.username || this.get('username');\n\n if (!username || username === '') {\n error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up user with an empty name.');\n throw error;\n }\n\n var password = attrs && attrs.password || this.get('password');\n\n if (!password || password === '') {\n error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up user with an empty password.');\n throw error;\n }\n\n return this.save(attrs, options).then(function (model) {\n if (model.isAnonymous()) {\n model.unset(\"authData.\".concat(PLATFORM_ANONYMOUS));\n model._opSetQueue = [{}];\n }\n\n return model._handleSaveResult(true).then(function () {\n return model;\n });\n });\n },\n\n /**\n * Signs up a new user with mobile phone and sms code.\n * You should call this instead of save for\n * new AV.Users. This will create a new AV.User on the server, and\n * also persist the session on disk so that you can access the user using\n *current
.\n *\n * A username and password must be set before calling signUp.
\n *\n * @param {Object} attrs Extra fields to set on the new user, or null.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the signup\n * finishes.\n * @see AV.User.signUpOrlogInWithMobilePhone\n * @see AV.Cloud.requestSmsCode\n */\n signUpOrlogInWithMobilePhone: function signUpOrlogInWithMobilePhone(attrs) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var error;\n var mobilePhoneNumber = attrs && attrs.mobilePhoneNumber || this.get('mobilePhoneNumber');\n\n if (!mobilePhoneNumber || mobilePhoneNumber === '') {\n error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up or login user by mobilePhoneNumber ' + 'with an empty mobilePhoneNumber.');\n throw error;\n }\n\n var smsCode = attrs && attrs.smsCode || this.get('smsCode');\n\n if (!smsCode || smsCode === '') {\n error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up or login user by mobilePhoneNumber ' + 'with an empty smsCode.');\n throw error;\n }\n\n options._makeRequest = function (route, className, id, method, json) {\n return AVRequest('usersByMobilePhone', null, null, 'POST', json);\n };\n\n return this.save(attrs, options).then(function (model) {\n delete model.attributes.smsCode;\n delete model._serverData.smsCode;\n return model._handleSaveResult(true).then(function () {\n return model;\n });\n });\n },\n\n /**\n * The same with {@link AV.User.loginWithAuthData}, except that you can set attributes before login.\n * @since 3.7.0\n */\n loginWithAuthData: function loginWithAuthData(authData, platform, options) {\n return this._linkWith(platform, authData, options);\n },\n\n /**\n * The same with {@link AV.User.loginWithAuthDataAndUnionId}, except that you can set attributes before login.\n * @since 3.7.0\n */\n loginWithAuthDataAndUnionId: function loginWithAuthDataAndUnionId(authData, platform, unionId, unionLoginOptions) {\n return this.loginWithAuthData(mergeUnionDataIntoAuthData()(authData, unionId, unionLoginOptions), platform, unionLoginOptions);\n },\n\n /**\n * The same with {@link AV.User.loginWithWeapp}, except that you can set attributes before login.\n * @deprecated please use {@link AV.User#loginWithMiniApp}\n * @since 3.7.0\n * @param {Object} [options]\n * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @param {boolean} [options.preferUnionId] 当用户满足 {@link https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html 获取 UnionId 的条件} 时,是否使用 UnionId 登录。(since 3.13.0)\n * @param {string} [options.unionIdPlatform = 'weixin'] (only take effect when preferUnionId) unionId platform\n * @param {boolean} [options.asMainAccount = true] (only take effect when preferUnionId) If true, the unionId will be associated with the user.\n * @return {Promisecurrent
.\n *\n * A username and password must be set before calling logIn.
\n *\n * @see AV.User.logIn\n * @return {Promise} A promise that is fulfilled with the user when\n * the login is complete.\n */\n logIn: function logIn() {\n var model = this;\n var request = AVRequest('login', null, null, 'POST', this.toJSON());\n return request.then(function (resp) {\n var serverAttrs = model.parse(resp);\n\n model._finishFetch(serverAttrs);\n\n return model._handleSaveResult(true).then(function () {\n if (!serverAttrs.smsCode) delete model.attributes['smsCode'];\n return model;\n });\n });\n },\n\n /**\n * @see AV.Object#save\n */\n save: function save(arg1, arg2, arg3) {\n var attrs, options;\n\n if (_.isObject(arg1) || _.isNull(arg1) || _.isUndefined(arg1)) {\n attrs = arg1;\n options = arg2;\n } else {\n attrs = {};\n attrs[arg1] = arg2;\n options = arg3;\n }\n\n options = options || {};\n return AV.Object.prototype.save.call(this, attrs, options).then(function (model) {\n return model._handleSaveResult(false).then(function () {\n return model;\n });\n });\n },\n\n /**\n * Follow a user\n * @since 0.3.0\n * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user.\n * @param {AV.User | String} options.user The target user or user's objectId to follow.\n * @param {Object} [options.attributes] key-value attributes dictionary to be used as\n * conditions of followerQuery/followeeQuery.\n * @param {AuthOptions} [authOptions]\n */\n follow: function follow(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n\n var user;\n var attributes;\n\n if (options.user) {\n user = options.user;\n attributes = options.attributes;\n } else {\n user = options;\n }\n\n var userObjectId = _.isString(user) ? user : user.id;\n\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n\n var route = 'users/' + this.id + '/friendship/' + userObjectId;\n var request = AVRequest(route, null, null, 'POST', AV._encode(attributes), authOptions);\n return request;\n },\n\n /**\n * Unfollow a user.\n * @since 0.3.0\n * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user.\n * @param {AV.User | String} options.user The target user or user's objectId to unfollow.\n * @param {AuthOptions} [authOptions]\n */\n unfollow: function unfollow(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n\n var user;\n\n if (options.user) {\n user = options.user;\n } else {\n user = options;\n }\n\n var userObjectId = _.isString(user) ? user : user.id;\n\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n\n var route = 'users/' + this.id + '/friendship/' + userObjectId;\n var request = AVRequest(route, null, null, 'DELETE', null, authOptions);\n return request;\n },\n\n /**\n * Get the user's followers and followees.\n * @since 4.8.0\n * @param {Object} [options]\n * @param {Number} [options.skip]\n * @param {Number} [options.limit]\n * @param {AuthOptions} [authOptions]\n */\n getFollowersAndFollowees: function getFollowersAndFollowees(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n\n return request({\n method: 'GET',\n path: \"/users/\".concat(this.id, \"/followersAndFollowees\"),\n query: {\n skip: options && options.skip,\n limit: options && options.limit,\n include: 'follower,followee',\n keys: 'follower,followee'\n },\n authOptions: authOptions\n }).then(function (_ref11) {\n var followers = _ref11.followers,\n followees = _ref11.followees;\n return {\n followers: (0, _map.default)(followers).call(followers, function (_ref12) {\n var follower = _ref12.follower;\n return AV._decode(follower);\n }),\n followees: (0, _map.default)(followees).call(followees, function (_ref13) {\n var followee = _ref13.followee;\n return AV._decode(followee);\n })\n };\n });\n },\n\n /**\n *Create a follower query to query the user's followers.\n * @since 0.3.0\n * @see AV.User#followerQuery\n */\n followerQuery: function followerQuery() {\n return AV.User.followerQuery(this.id);\n },\n\n /**\n *Create a followee query to query the user's followees.\n * @since 0.3.0\n * @see AV.User#followeeQuery\n */\n followeeQuery: function followeeQuery() {\n return AV.User.followeeQuery(this.id);\n },\n\n /**\n * @see AV.Object#fetch\n */\n fetch: function fetch(fetchOptions, options) {\n return AV.Object.prototype.fetch.call(this, fetchOptions, options).then(function (model) {\n return model._handleSaveResult(false).then(function () {\n return model;\n });\n });\n },\n\n /**\n * Update user's new password safely based on old password.\n * @param {String} oldPassword the old password.\n * @param {String} newPassword the new password.\n * @param {AuthOptions} options\n */\n updatePassword: function updatePassword(oldPassword, newPassword, options) {\n var _this12 = this;\n\n var route = 'users/' + this.id + '/updatePassword';\n var params = {\n old_password: oldPassword,\n new_password: newPassword\n };\n var request = AVRequest(route, null, null, 'PUT', params, options);\n return request.then(function (resp) {\n _this12._finishFetch(_this12.parse(resp));\n\n return _this12._handleSaveResult(true).then(function () {\n return resp;\n });\n });\n },\n\n /**\n * Returns true ifcurrent
would return this user.\n * @see AV.User#current\n */\n isCurrent: function isCurrent() {\n return this._isCurrentUser;\n },\n\n /**\n * Returns get(\"username\").\n * @return {String}\n * @see AV.Object#get\n */\n getUsername: function getUsername() {\n return this.get('username');\n },\n\n /**\n * Returns get(\"mobilePhoneNumber\").\n * @return {String}\n * @see AV.Object#get\n */\n getMobilePhoneNumber: function getMobilePhoneNumber() {\n return this.get('mobilePhoneNumber');\n },\n\n /**\n * Calls set(\"mobilePhoneNumber\", phoneNumber, options) and returns the result.\n * @param {String} mobilePhoneNumber\n * @return {Boolean}\n * @see AV.Object#set\n */\n setMobilePhoneNumber: function setMobilePhoneNumber(phone, options) {\n return this.set('mobilePhoneNumber', phone, options);\n },\n\n /**\n * Calls set(\"username\", username, options) and returns the result.\n * @param {String} username\n * @return {Boolean}\n * @see AV.Object#set\n */\n setUsername: function setUsername(username, options) {\n return this.set('username', username, options);\n },\n\n /**\n * Calls set(\"password\", password, options) and returns the result.\n * @param {String} password\n * @return {Boolean}\n * @see AV.Object#set\n */\n setPassword: function setPassword(password, options) {\n return this.set('password', password, options);\n },\n\n /**\n * Returns get(\"email\").\n * @return {String}\n * @see AV.Object#get\n */\n getEmail: function getEmail() {\n return this.get('email');\n },\n\n /**\n * Calls set(\"email\", email, options) and returns the result.\n * @param {String} email\n * @param {AuthOptions} options\n * @return {Boolean}\n * @see AV.Object#set\n */\n setEmail: function setEmail(email, options) {\n return this.set('email', email, options);\n },\n\n /**\n * Checks whether this user is the current user and has been authenticated.\n * @deprecated 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),\n * 如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id\n * @return (Boolean) whether this user is the current user and is logged in.\n */\n authenticated: function authenticated() {\n console.warn('DEPRECATED: 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id。');\n return !!this._sessionToken && !AV._config.disableCurrentUser && AV.User.current() && AV.User.current().id === this.id;\n },\n\n /**\n * Detects if current sessionToken is valid.\n *\n * @since 2.0.0\n * @return Promise.current
.\n *\n * @param {String} username The username (or email) to log in with.\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logIn: function logIn(username, password) {\n var user = AV.Object._create('_User');\n\n user._finishFetch({\n username: username,\n password: password\n });\n\n return user.logIn();\n },\n\n /**\n * Logs in a user with a session token. On success, this saves the session\n * to disk, so you can retrieve the currently logged in user using\n * current
.\n *\n * @param {String} sessionToken The sessionToken to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n */\n become: function become(sessionToken) {\n return this._fetchUserBySessionToken(sessionToken).then(function (user) {\n return user._handleSaveResult(true).then(function () {\n return user;\n });\n });\n },\n _fetchUserBySessionToken: function _fetchUserBySessionToken(sessionToken) {\n if (sessionToken === undefined) {\n return _promise.default.reject(new Error('The sessionToken cannot be undefined'));\n }\n\n var user = AV.Object._create('_User');\n\n return request({\n method: 'GET',\n path: '/users/me',\n authOptions: {\n sessionToken: sessionToken\n }\n }).then(function (resp) {\n var serverAttrs = user.parse(resp);\n\n user._finishFetch(serverAttrs);\n\n return user;\n });\n },\n\n /**\n * Logs in a user with a mobile phone number and sms code sent by\n * AV.User.requestLoginSmsCode.On success, this\n * saves the session to disk, so you can retrieve the currently logged in\n * user using current
.\n *\n * @param {String} mobilePhone The user's mobilePhoneNumber\n * @param {String} smsCode The sms code sent by AV.User.requestLoginSmsCode\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logInWithMobilePhoneSmsCode: function logInWithMobilePhoneSmsCode(mobilePhone, smsCode) {\n var user = AV.Object._create('_User');\n\n user._finishFetch({\n mobilePhoneNumber: mobilePhone,\n smsCode: smsCode\n });\n\n return user.logIn();\n },\n\n /**\n * Signs up or logs in a user with a mobilePhoneNumber and smsCode.\n * On success, this saves the session to disk, so you can retrieve the currently\n * logged in user using current
.\n *\n * @param {String} mobilePhoneNumber The user's mobilePhoneNumber.\n * @param {String} smsCode The sms code sent by AV.Cloud.requestSmsCode\n * @param {Object} attributes The user's other attributes such as username etc.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#signUpOrlogInWithMobilePhone\n * @see AV.Cloud.requestSmsCode\n */\n signUpOrlogInWithMobilePhone: function signUpOrlogInWithMobilePhone(mobilePhoneNumber, smsCode, attrs, options) {\n attrs = attrs || {};\n attrs.mobilePhoneNumber = mobilePhoneNumber;\n attrs.smsCode = smsCode;\n\n var user = AV.Object._create('_User');\n\n return user.signUpOrlogInWithMobilePhone(attrs, options);\n },\n\n /**\n * Logs in a user with a mobile phone number and password. On success, this\n * saves the session to disk, so you can retrieve the currently logged in\n * user using current
.\n *\n * @param {String} mobilePhone The user's mobilePhoneNumber\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logInWithMobilePhone: function logInWithMobilePhone(mobilePhone, password) {\n var user = AV.Object._create('_User');\n\n user._finishFetch({\n mobilePhoneNumber: mobilePhone,\n password: password\n });\n\n return user.logIn();\n },\n\n /**\n * Logs in a user with email and password.\n *\n * @since 3.13.0\n * @param {String} email The user's email.\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n */\n loginWithEmail: function loginWithEmail(email, password) {\n var user = AV.Object._create('_User');\n\n user._finishFetch({\n email: email,\n password: password\n });\n\n return user.logIn();\n },\n\n /**\n * Signs up or logs in a user with a third party auth data(AccessToken).\n * On success, this saves the session to disk, so you can retrieve the currently\n * logged in user using current
.\n *\n * @since 3.7.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @param {Object} [options]\n * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @example AV.User.loginWithAuthData({\n * openid: 'abc123',\n * access_token: '123abc',\n * expires_in: 1382686496\n * }, 'weixin').then(function(user) {\n * //Access user here\n * }).catch(function(error) {\n * //console.error(\"error: \", error);\n * });\n * @see {@link https://leancloud.cn/docs/js_guide.html#绑定第三方平台账户}\n */\n loginWithAuthData: function loginWithAuthData(authData, platform, options) {\n return AV.User._logInWith(platform, authData, options);\n },\n\n /**\n * @deprecated renamed to {@link AV.User.loginWithAuthData}\n */\n signUpOrlogInWithAuthData: function signUpOrlogInWithAuthData() {\n console.warn('DEPRECATED: User.signUpOrlogInWithAuthData 已废弃,请使用 User#loginWithAuthData 代替');\n return this.loginWithAuthData.apply(this, arguments);\n },\n\n /**\n * Signs up or logs in a user with a third party authData and unionId.\n * @since 3.7.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @param {string} unionId\n * @param {Object} [unionLoginOptions]\n * @param {string} [unionLoginOptions.unionIdPlatform = 'weixin'] unionId platform\n * @param {boolean} [unionLoginOptions.asMainAccount = false] If true, the unionId will be associated with the user.\n * @param {boolean} [unionLoginOptions.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @return {Promisecurrent
will return null
.\n * @return {Promise}\n */\n logOut: function logOut() {\n if (AV._config.disableCurrentUser) {\n console.warn('AV.User.current() was disabled in multi-user environment, call logOut() from user object instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html');\n return _promise.default.resolve(null);\n }\n\n if (AV.User._currentUser !== null) {\n AV.User._currentUser._logOutWithAll();\n\n AV.User._currentUser._isCurrentUser = false;\n }\n\n AV.User._currentUserMatchesDisk = true;\n AV.User._currentUser = null;\n return AV.localStorage.removeItemAsync(AV._getAVPath(AV.User._CURRENT_USER_KEY)).then(function () {\n return AV._refreshSubscriptionId();\n });\n },\n\n /**\n *Create a follower query for special user to query the user's followers.\n * @param {String} userObjectId The user object id.\n * @return {AV.FriendShipQuery}\n * @since 0.3.0\n */\n followerQuery: function followerQuery(userObjectId) {\n if (!userObjectId || !_.isString(userObjectId)) {\n throw new Error('Invalid user object id.');\n }\n\n var query = new AV.FriendShipQuery('_Follower');\n query._friendshipTag = 'follower';\n query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));\n return query;\n },\n\n /**\n *Create a followee query for special user to query the user's followees.\n * @param {String} userObjectId The user object id.\n * @return {AV.FriendShipQuery}\n * @since 0.3.0\n */\n followeeQuery: function followeeQuery(userObjectId) {\n if (!userObjectId || !_.isString(userObjectId)) {\n throw new Error('Invalid user object id.');\n }\n\n var query = new AV.FriendShipQuery('_Followee');\n query._friendshipTag = 'followee';\n query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));\n return query;\n },\n\n /**\n * Requests a password reset email to be sent to the specified email address\n * associated with the user account. This email allows the user to securely\n * reset their password on the AV site.\n *\n * @param {String} email The email address associated with the user that\n * forgot their password.\n * @return {Promise}\n */\n requestPasswordReset: function requestPasswordReset(email) {\n var json = {\n email: email\n };\n var request = AVRequest('requestPasswordReset', null, null, 'POST', json);\n return request;\n },\n\n /**\n * Requests a verify email to be sent to the specified email address\n * associated with the user account. This email allows the user to securely\n * verify their email address on the AV site.\n *\n * @param {String} email The email address associated with the user that\n * doesn't verify their email address.\n * @return {Promise}\n */\n requestEmailVerify: function requestEmailVerify(email) {\n var json = {\n email: email\n };\n var request = AVRequest('requestEmailVerify', null, null, 'POST', json);\n return request;\n },\n\n /**\n * Requests a verify sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * verify their mobile phone number by calling AV.User.verifyMobilePhone\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that doesn't verify their mobile phone number.\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestMobilePhoneVerify: function requestMobilePhoneVerify(mobilePhoneNumber) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var data = {\n mobilePhoneNumber: mobilePhoneNumber\n };\n\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n\n var request = AVRequest('requestMobilePhoneVerify', null, null, 'POST', data, options);\n return request;\n },\n\n /**\n * Requests a reset password sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * reset their account's password by calling AV.User.resetPasswordBySmsCode\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that doesn't verify their mobile phone number.\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestPasswordResetBySmsCode: function requestPasswordResetBySmsCode(mobilePhoneNumber) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var data = {\n mobilePhoneNumber: mobilePhoneNumber\n };\n\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n\n var request = AVRequest('requestPasswordResetBySmsCode', null, null, 'POST', data, options);\n return request;\n },\n\n /**\n * Requests a change mobile phone number sms code to be sent to the mobilePhoneNumber.\n * This sms code allows current user to reset it's mobilePhoneNumber by\n * calling {@link AV.User.changePhoneNumber}\n * @since 4.7.0\n * @param {String} mobilePhoneNumber\n * @param {Number} [ttl] ttl of sms code (default is 6 minutes)\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestChangePhoneNumber: function requestChangePhoneNumber(mobilePhoneNumber, ttl, options) {\n var data = {\n mobilePhoneNumber: mobilePhoneNumber\n };\n\n if (ttl) {\n data.ttl = options.ttl;\n }\n\n if (options && options.validateToken) {\n data.validate_token = options.validateToken;\n }\n\n return AVRequest('requestChangePhoneNumber', null, null, 'POST', data, options);\n },\n\n /**\n * Makes a call to reset user's account mobilePhoneNumber by sms code.\n * The sms code is sent by {@link AV.User.requestChangePhoneNumber}\n * @since 4.7.0\n * @param {String} mobilePhoneNumber\n * @param {String} code The sms code.\n * @return {Promise}\n */\n changePhoneNumber: function changePhoneNumber(mobilePhoneNumber, code) {\n var data = {\n mobilePhoneNumber: mobilePhoneNumber,\n code: code\n };\n return AVRequest('changePhoneNumber', null, null, 'POST', data);\n },\n\n /**\n * Makes a call to reset user's account password by sms code and new password.\n * The sms code is sent by AV.User.requestPasswordResetBySmsCode.\n * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode\n * @param {String} password The new password.\n * @param {String} mobilePhoneNumber\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n resetPasswordBySmsCode: function resetPasswordBySmsCode(code, password, mobilePhoneNumber) {\n var json = {\n password: password,\n mobilePhoneNumber: mobilePhoneNumber\n };\n var request = AVRequest('resetPasswordBySmsCode', null, code, 'PUT', json);\n return request;\n },\n\n /**\n * Makes a call to verify sms code that sent by AV.User.Cloud.requestSmsCode\n * If verify successfully,the user mobilePhoneVerified attribute will be true.\n * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode\n * @param {String} mobilePhoneNumber\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n verifyMobilePhone: function verifyMobilePhone(code, mobilePhoneNumber) {\n var json = {\n mobilePhoneNumber: mobilePhoneNumber\n };\n var request = AVRequest('verifyMobilePhone', null, code, 'POST', json);\n return request;\n },\n\n /**\n * Requests a logIn sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * login by AV.User.logInWithMobilePhoneSmsCode function.\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that want to login by AV.User.logInWithMobilePhoneSmsCode\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestLoginSmsCode: function requestLoginSmsCode(mobilePhoneNumber) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var data = {\n mobilePhoneNumber: mobilePhoneNumber\n };\n\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n\n var request = AVRequest('requestLoginSmsCode', null, null, 'POST', data, options);\n return request;\n },\n\n /**\n * Retrieves the currently logged in AVUser with a valid session,\n * either from memory or localStorage, if necessary.\n * @return {Promise.AV.Query defines a query that is used to fetch AV.Objects. The\n * most common use case is finding all objects that match a query through the\n * find
method. For example, this sample code fetches all objects\n * of class MyClass
. It calls a different function depending on\n * whether the fetch succeeded or not.\n *\n *
\n * var query = new AV.Query(MyClass);\n * query.find().then(function(results) {\n * // results is an array of AV.Object.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n *\n *
An AV.Query can also be used to retrieve a single object whose id is\n * known, through the get method. For example, this sample code fetches an\n * object of class MyClass
and id myId
. It calls a\n * different function depending on whether the fetch succeeded or not.\n *\n *
\n * var query = new AV.Query(MyClass);\n * query.get(myId).then(function(object) {\n * // object is an instance of AV.Object.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n *\n *
An AV.Query can also be used to count the number of objects that match\n * the query without retrieving all of those objects. For example, this\n * sample code counts the number of objects of the class MyClass
\n *
\n * var query = new AV.Query(MyClass);\n * query.count().then(function(number) {\n * // There are number instances of MyClass.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n */\n AV.Query = function (objectClass) {\n if (_.isString(objectClass)) {\n objectClass = AV.Object._getSubclass(objectClass);\n }\n\n this.objectClass = objectClass;\n this.className = objectClass.prototype.className;\n this._where = {};\n this._include = [];\n this._select = [];\n this._limit = -1; // negative limit means, do not send a limit\n\n this._skip = 0;\n this._defaultParams = {};\n };\n /**\n * Constructs a AV.Query that is the OR of the passed in queries. For\n * example:\n *
var compoundQuery = AV.Query.or(query1, query2, query3);\n *\n * will create a compoundQuery that is an or of the query1, query2, and\n * query3.\n * @param {...AV.Query} var_args The list of queries to OR.\n * @return {AV.Query} The query that is the OR of the passed in queries.\n */\n\n\n AV.Query.or = function () {\n var queries = _.toArray(arguments);\n\n var className = null;\n\n AV._arrayEach(queries, function (q) {\n if (_.isNull(className)) {\n className = q.className;\n }\n\n if (className !== q.className) {\n throw new Error('All queries must be for the same class');\n }\n });\n\n var query = new AV.Query(className);\n\n query._orQuery(queries);\n\n return query;\n };\n /**\n * Constructs a AV.Query that is the AND of the passed in queries. For\n * example:\n *
var compoundQuery = AV.Query.and(query1, query2, query3);\n *\n * will create a compoundQuery that is an 'and' of the query1, query2, and\n * query3.\n * @param {...AV.Query} var_args The list of queries to AND.\n * @return {AV.Query} The query that is the AND of the passed in queries.\n */\n\n\n AV.Query.and = function () {\n var queries = _.toArray(arguments);\n\n var className = null;\n\n AV._arrayEach(queries, function (q) {\n if (_.isNull(className)) {\n className = q.className;\n }\n\n if (className !== q.className) {\n throw new Error('All queries must be for the same class');\n }\n });\n\n var query = new AV.Query(className);\n\n query._andQuery(queries);\n\n return query;\n };\n /**\n * Retrieves a list of AVObjects that satisfy the CQL.\n * CQL syntax please see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.\n *\n * @param {String} cql A CQL string, see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.\n * @param {Array} pvalues An array contains placeholder values.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is resolved with the results when\n * the query completes.\n */\n\n\n AV.Query.doCloudQuery = function (cql, pvalues, options) {\n var params = {\n cql: cql\n };\n\n if (_.isArray(pvalues)) {\n params.pvalues = pvalues;\n } else {\n options = pvalues;\n }\n\n var request = _request('cloudQuery', null, null, 'GET', params, options);\n\n return request.then(function (response) {\n //query to process results.\n var query = new AV.Query(response.className);\n var results = (0, _map.default)(_).call(_, response.results, function (json) {\n var obj = query._newObject(response);\n\n if (obj._finishFetch) {\n obj._finishFetch(query._processResult(json), true);\n }\n\n return obj;\n });\n return {\n results: results,\n count: response.count,\n className: response.className\n };\n });\n };\n /**\n * Return a query with conditions from json.\n * This can be useful to send a query from server side to client side.\n * @since 4.0.0\n * @param {Object} json from {@link AV.Query#toJSON}\n * @return {AV.Query}\n */\n\n\n AV.Query.fromJSON = function (_ref) {\n var className = _ref.className,\n where = _ref.where,\n include = _ref.include,\n select = _ref.select,\n includeACL = _ref.includeACL,\n limit = _ref.limit,\n skip = _ref.skip,\n order = _ref.order;\n\n if (typeof className !== 'string') {\n throw new TypeError('Invalid Query JSON, className must be a String.');\n }\n\n var query = new AV.Query(className);\n\n _.extend(query, {\n _where: where,\n _include: include,\n _select: select,\n _includeACL: includeACL,\n _limit: limit,\n _skip: skip,\n _order: order\n });\n\n return query;\n };\n\n AV.Query._extend = AV._extend;\n\n _.extend(AV.Query.prototype,\n /** @lends AV.Query.prototype */\n {\n //hook to iterate result. Added by dennis
\n * Some functions are only available from Cloud Code.\n *
\n *\n * @namespace\n * @borrows AV.Captcha.request as requestCaptcha\n */\n AV.Cloud = AV.Cloud || {};\n\n _.extend(AV.Cloud,\n /** @lends AV.Cloud */\n {\n /**\n * Makes a call to a cloud function.\n * @param {String} name The function name.\n * @param {Object} [data] The parameters to send to the cloud function.\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n run: function run(name, data, options) {\n return request({\n service: 'engine',\n method: 'POST',\n path: \"/functions/\".concat(name),\n data: AV._encode(data, null, true),\n authOptions: options\n }).then(function (resp) {\n return AV._decode(resp).result;\n });\n },\n\n /**\n * Makes a call to a cloud function, you can send {AV.Object} as param or a field of param; the response\n * from server will also be parsed as an {AV.Object}, array of {AV.Object}, or object includes {AV.Object}\n * @param {String} name The function name.\n * @param {Object} [data] The parameters to send to the cloud function.\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result of the function.\n */\n rpc: function rpc(name, data, options) {\n if (_.isArray(data)) {\n return _promise.default.reject(new Error(\"Can't pass Array as the param of rpc function in JavaScript SDK.\"));\n }\n\n return request({\n service: 'engine',\n method: 'POST',\n path: \"/call/\".concat(name),\n data: AV._encodeObjectOrArray(data),\n authOptions: options\n }).then(function (resp) {\n return AV._decode(resp).result;\n });\n },\n\n /**\n * Make a call to request server date time.\n * @return {Promise.Send a status from current signined user to other user's private status inbox.
\n * @since 0.3.0\n * @param {AV.Status} status A status object to be send to followers.\n * @param {String} target The target user or user's objectId.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the send\n * completes.\n * @example\n * // send a private status to user '52e84e47e4b0f8de283b079b'\n * var status = new AVStatus('image url', 'a message');\n * AV.Status.sendPrivateStatus(status, '52e84e47e4b0f8de283b079b').then(function(){\n * //send status successfully.\n * }, function(err){\n * //an error threw.\n * console.dir(err);\n * });\n */\n\n\n AV.Status.sendPrivateStatus = function (status, target) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n if (!getSessionToken(options) && !AV.User.current()) {\n throw new Error('Please signin an user.');\n }\n\n if (!target) {\n throw new Error('Invalid target user.');\n }\n\n var userObjectId = _.isString(target) ? target : target.id;\n\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n\n return getUserPointer(options).then(function (currUser) {\n var query = {};\n query.className = '_User';\n query.where = {\n objectId: userObjectId\n };\n var data = {};\n data.query = query;\n status.data = status.data || {};\n status.data.source = status.data.source || currUser;\n data.data = status._getDataJSON();\n data.inboxType = 'private';\n status.inboxType = 'private';\n var request = AVRequest('statuses', null, null, 'POST', data, options);\n return request.then(function (response) {\n status.id = response.objectId;\n status.createdAt = AV._parseDate(response.createdAt);\n return status;\n });\n });\n };\n /**\n * Count unread statuses in someone's inbox.\n * @since 0.3.0\n * @param {AV.User} owner The status owner.\n * @param {String} inboxType The inbox type, 'default' by default.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the count\n * completes.\n * @example\n * AV.Status.countUnreadStatuses(AV.User.current()).then(function(response){\n * console.log(response.unread); //unread statuses number.\n * console.log(response.total); //total statuses number.\n * });\n */\n\n\n AV.Status.countUnreadStatuses = function (owner) {\n var inboxType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default';\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n if (!_.isString(inboxType)) options = inboxType;\n\n if (!getSessionToken(options) && owner == null && !AV.User.current()) {\n throw new Error('Please signin an user or pass the owner objectId.');\n }\n\n return _promise.default.resolve(owner || getUser(options)).then(function (owner) {\n var params = {};\n params.inboxType = AV._encode(inboxType);\n params.owner = AV._encode(owner);\n return AVRequest('subscribe/statuses/count', null, null, 'GET', params, options);\n });\n };\n /**\n * reset unread statuses count in someone's inbox.\n * @since 2.1.0\n * @param {AV.User} owner The status owner.\n * @param {String} inboxType The inbox type, 'default' by default.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the reset\n * completes.\n * @example\n * AV.Status.resetUnreadCount(AV.User.current()).then(function(response){\n * console.log(response.unread); //unread statuses number.\n * console.log(response.total); //total statuses number.\n * });\n */\n\n\n AV.Status.resetUnreadCount = function (owner) {\n var inboxType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default';\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n if (!_.isString(inboxType)) options = inboxType;\n\n if (!getSessionToken(options) && owner == null && !AV.User.current()) {\n throw new Error('Please signin an user or pass the owner objectId.');\n }\n\n return _promise.default.resolve(owner || getUser(options)).then(function (owner) {\n var params = {};\n params.inboxType = AV._encode(inboxType);\n params.owner = AV._encode(owner);\n return AVRequest('subscribe/statuses/resetUnreadCount', null, null, 'POST', params, options);\n });\n };\n /**\n * Create a status query to find someone's published statuses.\n * @since 0.3.0\n * @param {AV.User} source The status source, typically the publisher.\n * @return {AV.Query} The query object for status.\n * @example\n * //Find current user's published statuses.\n * var query = AV.Status.statusQuery(AV.User.current());\n * query.find().then(function(statuses){\n * //process statuses\n * });\n */\n\n\n AV.Status.statusQuery = function (source) {\n var query = new AV.Query('_Status');\n\n if (source) {\n query.equalTo('source', source);\n }\n\n return query;\n };\n /**\n *AV.InboxQuery defines a query that is used to fetch somebody's inbox statuses.
\n * @class\n */\n\n\n AV.InboxQuery = AV.Query._extend(\n /** @lends AV.InboxQuery.prototype */\n {\n _objectClass: AV.Status,\n _sinceId: 0,\n _maxId: 0,\n _inboxType: 'default',\n _owner: null,\n _newObject: function _newObject() {\n return new AV.Status();\n },\n _createRequest: function _createRequest(params, options) {\n return AV.InboxQuery.__super__._createRequest.call(this, params, options, '/subscribe/statuses');\n },\n\n /**\n * Sets the messageId of results to skip before returning any results.\n * This is useful for pagination.\n * Default is zero.\n * @param {Number} n the mesage id.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n sinceId: function sinceId(id) {\n this._sinceId = id;\n return this;\n },\n\n /**\n * Sets the maximal messageId of results。\n * This is useful for pagination.\n * Default is zero that is no limition.\n * @param {Number} n the mesage id.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n maxId: function maxId(id) {\n this._maxId = id;\n return this;\n },\n\n /**\n * Sets the owner of the querying inbox.\n * @param {AV.User} owner The inbox owner.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n owner: function owner(_owner) {\n this._owner = _owner;\n return this;\n },\n\n /**\n * Sets the querying inbox type.default is 'default'.\n * @param {String} type The inbox type.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n inboxType: function inboxType(type) {\n this._inboxType = type;\n return this;\n },\n _getParams: function _getParams() {\n var params = AV.InboxQuery.__super__._getParams.call(this);\n\n params.owner = AV._encode(this._owner);\n params.inboxType = AV._encode(this._inboxType);\n params.sinceId = AV._encode(this._sinceId);\n params.maxId = AV._encode(this._maxId);\n return params;\n }\n });\n /**\n * Create a inbox status query to find someone's inbox statuses.\n * @since 0.3.0\n * @param {AV.User} owner The inbox's owner\n * @param {String} inboxType The inbox type,'default' by default.\n * @return {AV.InboxQuery} The inbox query object.\n * @see AV.InboxQuery\n * @example\n * //Find current user's default inbox statuses.\n * var query = AV.Status.inboxQuery(AV.User.current());\n * //find the statuses after the last message id\n * query.sinceId(lastMessageId);\n * query.find().then(function(statuses){\n * //process statuses\n * });\n */\n\n AV.Status.inboxQuery = function (owner, inboxType) {\n var query = new AV.InboxQuery(AV.Status);\n\n if (owner) {\n query._owner = owner;\n }\n\n if (inboxType) {\n query._inboxType = inboxType;\n }\n\n return query;\n };\n};\n\n/***/ }),\n/* 535 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _interopRequireDefault = __webpack_require__(2);\n\nvar _stringify = _interopRequireDefault(__webpack_require__(34));\n\nvar _map = _interopRequireDefault(__webpack_require__(39));\n\nvar _ = __webpack_require__(1);\n\nvar AVRequest = __webpack_require__(25)._request;\n\nmodule.exports = function (AV) {\n /**\n * A builder to generate sort string for app searching.For example:\n * @class\n * @since 0.5.1\n * @example\n * var builder = new AV.SearchSortBuilder();\n * builder.ascending('key1').descending('key2','max');\n * var query = new AV.SearchQuery('Player');\n * query.sortBy(builder);\n * query.find().then();\n */\n AV.SearchSortBuilder = function () {\n this._sortFields = [];\n };\n\n _.extend(AV.SearchSortBuilder.prototype,\n /** @lends AV.SearchSortBuilder.prototype */\n {\n _addField: function _addField(key, order, mode, missing) {\n var field = {};\n field[key] = {\n order: order || 'asc',\n mode: mode || 'avg',\n missing: '_' + (missing || 'last')\n };\n\n this._sortFields.push(field);\n\n return this;\n },\n\n /**\n * Sorts the results in ascending order by the given key and options.\n *\n * @param {String} key The key to order by.\n * @param {String} mode The sort mode, default is 'avg', you can choose\n * 'max' or 'min' too.\n * @param {String} missing The missing key behaviour, default is 'last',\n * you can choose 'first' too.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n ascending: function ascending(key, mode, missing) {\n return this._addField(key, 'asc', mode, missing);\n },\n\n /**\n * Sorts the results in descending order by the given key and options.\n *\n * @param {String} key The key to order by.\n * @param {String} mode The sort mode, default is 'avg', you can choose\n * 'max' or 'min' too.\n * @param {String} missing The missing key behaviour, default is 'last',\n * you can choose 'first' too.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n descending: function descending(key, mode, missing) {\n return this._addField(key, 'desc', mode, missing);\n },\n\n /**\n * Add a proximity based constraint for finding objects with key point\n * values near the point given.\n * @param {String} key The key that the AV.GeoPoint is stored in.\n * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.\n * @param {Object} options The other options such as mode,order, unit etc.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n whereNear: function whereNear(key, point, options) {\n options = options || {};\n var field = {};\n var geo = {\n lat: point.latitude,\n lon: point.longitude\n };\n var m = {\n order: options.order || 'asc',\n mode: options.mode || 'avg',\n unit: options.unit || 'km'\n };\n m[key] = geo;\n field['_geo_distance'] = m;\n\n this._sortFields.push(field);\n\n return this;\n },\n\n /**\n * Build a sort string by configuration.\n * @return {String} the sort string.\n */\n build: function build() {\n return (0, _stringify.default)(AV._encode(this._sortFields));\n }\n });\n /**\n * App searching query.Use just like AV.Query:\n *\n * Visit App Searching Guide\n * for more details.\n * @class\n * @since 0.5.1\n * @example\n * var query = new AV.SearchQuery('Player');\n * query.queryString('*');\n * query.find().then(function(results) {\n * console.log('Found %d objects', query.hits());\n * //Process results\n * });\n */\n\n\n AV.SearchQuery = AV.Query._extend(\n /** @lends AV.SearchQuery.prototype */\n {\n _sid: null,\n _hits: 0,\n _queryString: null,\n _highlights: null,\n _sortBuilder: null,\n _clazz: null,\n constructor: function constructor(className) {\n if (className) {\n this._clazz = className;\n } else {\n className = '__INVALID_CLASS';\n }\n\n AV.Query.call(this, className);\n },\n _createRequest: function _createRequest(params, options) {\n return AVRequest('search/select', null, null, 'GET', params || this._getParams(), options);\n },\n\n /**\n * Sets the sid of app searching query.Default is null.\n * @param {String} sid Scroll id for searching.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n sid: function sid(_sid) {\n this._sid = _sid;\n return this;\n },\n\n /**\n * Sets the query string of app searching.\n * @param {String} q The query string.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n queryString: function queryString(q) {\n this._queryString = q;\n return this;\n },\n\n /**\n * Sets the highlight fields. Such as\n *\n * query.highlights('title');\n * //or pass an array.\n * query.highlights(['title', 'content'])\n *
\n * @param {String|String[]} highlights a list of fields.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n highlights: function highlights(_highlights) {\n var objects;\n\n if (_highlights && _.isString(_highlights)) {\n objects = _.toArray(arguments);\n } else {\n objects = _highlights;\n }\n\n this._highlights = objects;\n return this;\n },\n\n /**\n * Sets the sort builder for this query.\n * @see AV.SearchSortBuilder\n * @param { AV.SearchSortBuilder} builder The sort builder.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n *\n */\n sortBy: function sortBy(builder) {\n this._sortBuilder = builder;\n return this;\n },\n\n /**\n * Returns the number of objects that match this query.\n * @return {Number}\n */\n hits: function hits() {\n if (!this._hits) {\n this._hits = 0;\n }\n\n return this._hits;\n },\n _processResult: function _processResult(json) {\n delete json['className'];\n delete json['_app_url'];\n delete json['_deeplink'];\n return json;\n },\n\n /**\n * Returns true when there are more documents can be retrieved by this\n * query instance, you can call find function to get more results.\n * @see AV.SearchQuery#find\n * @return {Boolean}\n */\n hasMore: function hasMore() {\n return !this._hitEnd;\n },\n\n /**\n * Reset current query instance state(such as sid, hits etc) except params\n * for a new searching. After resetting, hasMore() will return true.\n */\n reset: function reset() {\n this._hitEnd = false;\n this._sid = null;\n this._hits = 0;\n },\n\n /**\n * Retrieves a list of AVObjects that satisfy this query.\n * Either options.success or options.error is called when the find\n * completes.\n *\n * @see AV.Query#find\n * @param {AuthOptions} options\n * @return {Promise} A promise that is resolved with the results when\n * the query completes.\n */\n find: function find(options) {\n var self = this;\n\n var request = this._createRequest(undefined, options);\n\n return request.then(function (response) {\n //update sid for next querying.\n if (response.sid) {\n self._oldSid = self._sid;\n self._sid = response.sid;\n } else {\n self._sid = null;\n self._hitEnd = true;\n }\n\n self._hits = response.hits || 0;\n return (0, _map.default)(_).call(_, response.results, function (json) {\n if (json.className) {\n response.className = json.className;\n }\n\n var obj = self._newObject(response);\n\n obj.appURL = json['_app_url'];\n\n obj._finishFetch(self._processResult(json), true);\n\n return obj;\n });\n });\n },\n _getParams: function _getParams() {\n var params = AV.SearchQuery.__super__._getParams.call(this);\n\n delete params.where;\n\n if (this._clazz) {\n params.clazz = this.className;\n }\n\n if (this._sid) {\n params.sid = this._sid;\n }\n\n if (!this._queryString) {\n throw new Error('Please set query string.');\n } else {\n params.q = this._queryString;\n }\n\n if (this._highlights) {\n params.highlights = this._highlights.join(',');\n }\n\n if (this._sortBuilder && params.order) {\n throw new Error('sort and order can not be set at same time.');\n }\n\n if (this._sortBuilder) {\n params.sort = this._sortBuilder.build();\n }\n\n return params;\n }\n });\n};\n/**\n * Sorts the results in ascending order by the given key.\n *\n * @method AV.SearchQuery#ascending\n * @param {String} key The key to order by.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n\n/**\n * Also sorts the results in ascending order by the given key. The previous sort keys have\n * precedence over this key.\n *\n * @method AV.SearchQuery#addAscending\n * @param {String} key The key to order by\n * @return {AV.SearchQuery} Returns the query so you can chain this call.\n */\n\n/**\n * Sorts the results in descending order by the given key.\n *\n * @method AV.SearchQuery#descending\n * @param {String} key The key to order by.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n\n/**\n * Also sorts the results in descending order by the given key. The previous sort keys have\n * precedence over this key.\n *\n * @method AV.SearchQuery#addDescending\n * @param {String} key The key to order by\n * @return {AV.SearchQuery} Returns the query so you can chain this call.\n */\n\n/**\n * Include nested AV.Objects for the provided key. You can use dot\n * notation to specify which fields in the included object are also fetch.\n * @method AV.SearchQuery#include\n * @param {String[]} keys The name of the key to include.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n\n/**\n * Sets the number of results to skip before returning any results.\n * This is useful for pagination.\n * Default is to skip zero results.\n * @method AV.SearchQuery#skip\n * @param {Number} n the number of results to skip.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n\n/**\n * Sets the limit of the number of results to return. The default limit is\n * 100, with a maximum of 1000 results being returned at a time.\n * @method AV.SearchQuery#limit\n * @param {Number} n the number of results to limit to.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n\n/***/ }),\n/* 536 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _interopRequireDefault = __webpack_require__(2);\n\nvar _promise = _interopRequireDefault(__webpack_require__(10));\n\nvar _ = __webpack_require__(1);\n\nvar AVError = __webpack_require__(40);\n\nvar _require = __webpack_require__(25),\n request = _require.request;\n\nmodule.exports = function (AV) {\n /**\n * 包含了使用了 LeanCloud\n * 离线数据分析功能的函数。\n * \n * 仅在云引擎运行环境下有效。\n *
\n * @namespace\n */\n AV.Insight = AV.Insight || {};\n\n _.extend(AV.Insight,\n /** @lends AV.Insight */\n {\n /**\n * 开始一个 Insight 任务。结果里将返回 Job id,你可以拿得到的 id 使用\n * AV.Insight.JobQuery 查询任务状态和结果。\n * @param {Object} jobConfig 任务配置的 JSON 对象,例如:\n * { \"sql\" : \"select count(*) as c,gender from _User group by gender\",\n * \"saveAs\": {\n * \"className\" : \"UserGender\",\n * \"limit\": 1\n * }\n * }\n *
\n * sql 指定任务执行的 SQL 语句, saveAs(可选) 指定将结果保存在哪张表里,limit 最大 1000。\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n startJob: function startJob(jobConfig, options) {\n if (!jobConfig || !jobConfig.sql) {\n throw new Error('Please provide the sql to run the job.');\n }\n\n var data = {\n jobConfig: jobConfig,\n appId: AV.applicationId\n };\n return request({\n path: '/bigquery/jobs',\n method: 'POST',\n data: AV._encode(data, null, true),\n authOptions: options,\n signKey: false\n }).then(function (resp) {\n return AV._decode(resp).id;\n });\n },\n\n /**\n * 监听 Insight 任务事件(未来推出独立部署的离线分析服务后开放)\n * \n * 仅在云引擎运行环境下有效。\n *
\n * @param {String} event 监听的事件,目前尚不支持。\n * @param {Function} 监听回调函数,接收 (err, id) 两个参数,err 表示错误信息,\n * id 表示任务 id。接下来你可以拿这个 id 使用AV.Insight.JobQuery 查询任务状态和结果。\n *\n */\n on: function on(event, cb) {}\n });\n /**\n * 创建一个对象,用于查询 Insight 任务状态和结果。\n * @class\n * @param {String} id 任务 id\n * @since 0.5.5\n */\n\n\n AV.Insight.JobQuery = function (id, className) {\n if (!id) {\n throw new Error('Please provide the job id.');\n }\n\n this.id = id;\n this.className = className;\n this._skip = 0;\n this._limit = 100;\n };\n\n _.extend(AV.Insight.JobQuery.prototype,\n /** @lends AV.Insight.JobQuery.prototype */\n {\n /**\n * Sets the number of results to skip before returning any results.\n * This is useful for pagination.\n * Default is to skip zero results.\n * @param {Number} n the number of results to skip.\n * @return {AV.Query} Returns the query, so you can chain this call.\n */\n skip: function skip(n) {\n this._skip = n;\n return this;\n },\n\n /**\n * Sets the limit of the number of results to return. The default limit is\n * 100, with a maximum of 1000 results being returned at a time.\n * @param {Number} n the number of results to limit to.\n * @return {AV.Query} Returns the query, so you can chain this call.\n */\n limit: function limit(n) {\n this._limit = n;\n return this;\n },\n\n /**\n * 查询任务状态和结果,任务结果为一个 JSON 对象,包括 status 表示任务状态, totalCount 表示总数,\n * results 数组表示任务结果数组,previewCount 表示可以返回的结果总数,任务的开始和截止时间\n * startTime、endTime 等信息。\n *\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n *\n */\n find: function find(options) {\n var params = {\n skip: this._skip,\n limit: this._limit\n };\n return request({\n path: \"/bigquery/jobs/\".concat(this.id),\n method: 'GET',\n query: params,\n authOptions: options,\n signKey: false\n }).then(function (response) {\n if (response.error) {\n return _promise.default.reject(new AVError(response.code, response.error));\n }\n\n return _promise.default.resolve(response);\n });\n }\n });\n};\n\n/***/ }),\n/* 537 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _interopRequireDefault = __webpack_require__(2);\n\nvar _promise = _interopRequireDefault(__webpack_require__(10));\n\nvar _ = __webpack_require__(1);\n\nvar _require = __webpack_require__(25),\n LCRequest = _require.request;\n\nvar _require2 = __webpack_require__(28),\n getSessionToken = _require2.getSessionToken;\n\nmodule.exports = function (AV) {\n var getUserWithSessionToken = function getUserWithSessionToken(authOptions) {\n if (authOptions.user) {\n if (!authOptions.user._sessionToken) {\n throw new Error('authOptions.user is not signed in.');\n }\n\n return _promise.default.resolve(authOptions.user);\n }\n\n if (authOptions.sessionToken) {\n return AV.User._fetchUserBySessionToken(authOptions.sessionToken);\n }\n\n return AV.User.currentAsync();\n };\n\n var getSessionTokenAsync = function getSessionTokenAsync(authOptions) {\n var sessionToken = getSessionToken(authOptions);\n\n if (sessionToken) {\n return _promise.default.resolve(sessionToken);\n }\n\n return AV.User.currentAsync().then(function (user) {\n if (user) {\n return user.getSessionToken();\n }\n });\n };\n /**\n * Contains functions to deal with Friendship in LeanCloud.\n * @class\n */\n\n\n AV.Friendship = {\n /**\n * Request friendship.\n * @since 4.8.0\n * @param {String | AV.User | Object} options if an AV.User or string is given, it will be used as the friend.\n * @param {AV.User | string} options.friend The friend (or friend's objectId) to follow.\n * @param {Object} [options.attributes] key-value attributes dictionary to be used as conditions of followeeQuery.\n * @param {AuthOptions} [authOptions]\n * @return {PromiseAn AV.Conversation is a local representation of a LeanCloud realtime's\n * conversation. This class is a subclass of AV.Object, and retains the\n * same functionality of an AV.Object, but also extends it with various\n * conversation specific methods, like get members, creators of this conversation.\n *
\n *\n * @class AV.Conversation\n * @param {String} name The name of the Role to create.\n * @param {Object} [options]\n * @param {Boolean} [options.isSystem] Set this conversation as system conversation.\n * @param {Boolean} [options.isTransient] Set this conversation as transient conversation.\n */\n\n\nmodule.exports = AV.Object.extend('_Conversation',\n/** @lends AV.Conversation.prototype */\n{\n constructor: function constructor(name) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n AV.Object.prototype.constructor.call(this, null, null);\n this.set('name', name);\n\n if (options.isSystem !== undefined) {\n this.set('sys', options.isSystem ? true : false);\n }\n\n if (options.isTransient !== undefined) {\n this.set('tr', options.isTransient ? true : false);\n }\n },\n\n /**\n * Get current conversation's creator.\n *\n * @return {String}\n */\n getCreator: function getCreator() {\n return this.get('c');\n },\n\n /**\n * Get the last message's time.\n *\n * @return {Date}\n */\n getLastMessageAt: function getLastMessageAt() {\n return this.get('lm');\n },\n\n /**\n * Get this conversation's members\n *\n * @return {String[]}\n */\n getMembers: function getMembers() {\n return this.get('m');\n },\n\n /**\n * Add a member to this conversation\n *\n * @param {String} member\n */\n addMember: function addMember(member) {\n return this.add('m', member);\n },\n\n /**\n * Get this conversation's members who set this conversation as muted.\n *\n * @return {String[]}\n */\n getMutedMembers: function getMutedMembers() {\n return this.get('mu');\n },\n\n /**\n * Get this conversation's name field.\n *\n * @return String\n */\n getName: function getName() {\n return this.get('name');\n },\n\n /**\n * Returns true if this conversation is transient conversation.\n *\n * @return {Boolean}\n */\n isTransient: function isTransient() {\n return this.get('tr');\n },\n\n /**\n * Returns true if this conversation is system conversation.\n *\n * @return {Boolean}\n */\n isSystem: function isSystem() {\n return this.get('sys');\n },\n\n /**\n * Send realtime message to this conversation, using HTTP request.\n *\n * @param {String} fromClient Sender's client id.\n * @param {String|Object} message The message which will send to conversation.\n * It could be a raw string, or an object with a `toJSON` method, like a\n * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息}\n * @param {Object} [options]\n * @param {Boolean} [options.transient] Whether send this message as transient message or not.\n * @param {String[]} [options.toClients] Ids of clients to send to. This option can be used only in system conversation.\n * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容}\n * @param {AuthOptions} [authOptions]\n * @return {Promise}\n */\n send: function send(fromClient, message) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var authOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n var data = {\n from_peer: fromClient,\n conv_id: this.id,\n transient: false,\n message: serializeMessage(message)\n };\n\n if (options.toClients !== undefined) {\n data.to_peers = options.toClients;\n }\n\n if (options.transient !== undefined) {\n data.transient = options.transient ? true : false;\n }\n\n if (options.pushData !== undefined) {\n data.push_data = options.pushData;\n }\n\n return _request('rtm', 'messages', null, 'POST', data, authOptions);\n },\n\n /**\n * Send realtime broadcast message to all clients, via this conversation, using HTTP request.\n *\n * @param {String} fromClient Sender's client id.\n * @param {String|Object} message The message which will send to conversation.\n * It could be a raw string, or an object with a `toJSON` method, like a\n * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息}.\n * @param {Object} [options]\n * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容}.\n * @param {Object} [options.validTill] The message will valid till this time.\n * @param {AuthOptions} [authOptions]\n * @return {Promise}\n */\n broadcast: function broadcast(fromClient, message) {\n var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var authOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n var data = {\n from_peer: fromClient,\n conv_id: this.id,\n message: serializeMessage(message)\n };\n\n if (options.pushData !== undefined) {\n data.push = options.pushData;\n }\n\n if (options.validTill !== undefined) {\n var ts = options.validTill;\n\n if (_.isDate(ts)) {\n ts = ts.getTime();\n }\n\n options.valid_till = ts;\n }\n\n return _request('rtm', 'broadcast', null, 'POST', data, authOptions);\n }\n});\n\n/***/ }),\n/* 539 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _interopRequireDefault = __webpack_require__(2);\n\nvar _promise = _interopRequireDefault(__webpack_require__(10));\n\nvar _map = _interopRequireDefault(__webpack_require__(39));\n\nvar _concat = _interopRequireDefault(__webpack_require__(29));\n\nvar _ = __webpack_require__(1);\n\nvar _require = __webpack_require__(25),\n request = _require.request;\n\nvar _require2 = __webpack_require__(28),\n ensureArray = _require2.ensureArray,\n parseDate = _require2.parseDate;\n\nvar AV = __webpack_require__(59);\n/**\n * The version change interval for Leaderboard\n * @enum\n */\n\n\nAV.LeaderboardVersionChangeInterval = {\n NEVER: 'never',\n DAY: 'day',\n WEEK: 'week',\n MONTH: 'month'\n};\n/**\n * The order of the leaderboard results\n * @enum\n */\n\nAV.LeaderboardOrder = {\n ASCENDING: 'ascending',\n DESCENDING: 'descending'\n};\n/**\n * The update strategy for Leaderboard\n * @enum\n */\n\nAV.LeaderboardUpdateStrategy = {\n /** Only keep the best statistic. If the leaderboard is in descending order, the best statistic is the highest one. */\n BETTER: 'better',\n\n /** Keep the last updated statistic */\n LAST: 'last',\n\n /** Keep the sum of all updated statistics */\n SUM: 'sum'\n};\n/**\n * @typedef {Object} Ranking\n * @property {number} rank Starts at 0\n * @property {number} value the statistic value of this ranking\n * @property {AV.User} user The user of this ranking\n * @property {Statistic[]} [includedStatistics] Other statistics of the user, specified by the `includeStatistic` option of `AV.Leaderboard.getResults()`\n */\n\n/**\n * @typedef {Object} LeaderboardArchive\n * @property {string} statisticName\n * @property {number} version version of the leaderboard\n * @property {string} status\n * @property {string} url URL for the downloadable archive\n * @property {Date} activatedAt time when this version became active\n * @property {Date} deactivatedAt time when this version was deactivated by a version incrementing\n */\n\n/**\n * @class\n */\n\nfunction Statistic(_ref) {\n var name = _ref.name,\n value = _ref.value,\n version = _ref.version;\n\n /**\n * @type {string}\n */\n this.name = name;\n /**\n * @type {number}\n */\n\n this.value = value;\n /**\n * @type {number?}\n */\n\n this.version = version;\n}\n\nvar parseStatisticData = function parseStatisticData(statisticData) {\n var _AV$_decode = AV._decode(statisticData),\n name = _AV$_decode.statisticName,\n value = _AV$_decode.statisticValue,\n version = _AV$_decode.version;\n\n return new Statistic({\n name: name,\n value: value,\n version: version\n });\n};\n/**\n * @class\n */\n\n\nAV.Leaderboard = function Leaderboard(statisticName) {\n /**\n * @type {string}\n */\n this.statisticName = statisticName;\n /**\n * @type {AV.LeaderboardOrder}\n */\n\n this.order = undefined;\n /**\n * @type {AV.LeaderboardUpdateStrategy}\n */\n\n this.updateStrategy = undefined;\n /**\n * @type {AV.LeaderboardVersionChangeInterval}\n */\n\n this.versionChangeInterval = undefined;\n /**\n * @type {number}\n */\n\n this.version = undefined;\n /**\n * @type {Date?}\n */\n\n this.nextResetAt = undefined;\n /**\n * @type {Date?}\n */\n\n this.createdAt = undefined;\n};\n\nvar Leaderboard = AV.Leaderboard;\n/**\n * Create an instance of Leaderboard for the give statistic name.\n * @param {string} statisticName\n * @return {AV.Leaderboard}\n */\n\nAV.Leaderboard.createWithoutData = function (statisticName) {\n return new Leaderboard(statisticName);\n};\n/**\n * (masterKey required) Create a new Leaderboard.\n * @param {Object} options\n * @param {string} options.statisticName\n * @param {AV.LeaderboardOrder} options.order\n * @param {AV.LeaderboardVersionChangeInterval} [options.versionChangeInterval] default to WEEK\n * @param {AV.LeaderboardUpdateStrategy} [options.updateStrategy] default to BETTER\n * @param {AuthOptions} [authOptions]\n * @return {PromiseAvailable in Cloud Code and Node.js only.\n *
\n */\n AV.Cloud.useMasterKey = () => {\n AV._config.useMasterKey = true;\n };\n}\n\n/**\n * Call this method to set production environment variable.\n * @function AV.setProduction\n * @param {Boolean} production True is production environment,and\n * it's true by default.\n */\nAV.setProduction = production => {\n if (!isNullOrUndefined(production)) {\n AV._config.production = production ? 1 : 0;\n } else {\n // change to default value\n AV._config.production = null;\n }\n};\n\nAV._setServerURLs = (urls, disableAppRouter = true) => {\n if (typeof urls !== 'string') {\n extend(AV._config.serverURLs, urls);\n } else {\n AV._config.serverURLs = fillServerURLs(urls);\n }\n if (disableAppRouter) {\n if (AV._appRouter) {\n AV._appRouter.disable();\n } else {\n _disableAppRouter = true;\n }\n }\n};\n/**\n * Set server URLs for services.\n * @function AV.setServerURL\n * @since 4.3.0\n * @param {String|ServerURLs} urls URLs for services. if a string was given, it will be applied for all services.\n * You can also set them when initializing SDK with `options.serverURL`\n */\nAV.setServerURL = urls => AV._setServerURLs(urls);\nAV.setServerURLs = AV.setServerURL;\n\nAV.keepErrorRawMessage = value => {\n AV._sharedConfig.keepErrorRawMessage = value;\n};\n\n/**\n * Set a deadline for requests to complete.\n * Note that file upload requests are not affected.\n * @function AV.setRequestTimeout\n * @since 3.6.0\n * @param {number} ms\n */\nAV.setRequestTimeout = ms => {\n AV._config.requestTimeout = ms;\n};\n\n// backword compatible\nAV.initialize = AV.init;\n\nconst defineConfig = property =>\n Object.defineProperty(AV, property, {\n get() {\n return AV._config[property];\n },\n set(value) {\n AV._config[property] = value;\n },\n });\n\n['applicationId', 'applicationKey', 'masterKey', 'hookKey'].forEach(\n defineConfig\n);\n\n\n\n// WEBPACK FOOTER //\n// ./src/init.js","var isPrototypeOf = require('../../internals/object-is-prototype-of');\nvar method = require('../array/virtual/slice');\n\nvar ArrayPrototype = Array.prototype;\n\nmodule.exports = function (it) {\n var own = it.slice;\n return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.slice) ? method : own;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/instance/slice.js\n// module id = 383\n// module chunks = 0 1","require('../../../modules/es.array.slice');\nvar entryVirtual = require('../../../internals/entry-virtual');\n\nmodule.exports = entryVirtual('Array').slice;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/virtual/slice.js\n// module id = 384\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar isArray = require('../internals/is-array');\nvar isConstructor = require('../internals/is-constructor');\nvar isObject = require('../internals/is-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar createProperty = require('../internals/create-property');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\nvar un$Slice = require('../internals/array-slice');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('slice');\n\nvar SPECIES = wellKnownSymbol('species');\nvar $Array = Array;\nvar max = Math.max;\n\n// `Array.prototype.slice` method\n// https://tc39.es/ecma262/#sec-array.prototype.slice\n// fallback for not array-like ES3 strings and DOM objects\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {\n slice: function slice(start, end) {\n var O = toIndexedObject(this);\n var length = lengthOfArrayLike(O);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible\n var Constructor, result, n;\n if (isArray(O)) {\n Constructor = O.constructor;\n // cross-realm fallback\n if (isConstructor(Constructor) && (Constructor === $Array || isArray(Constructor.prototype))) {\n Constructor = undefined;\n } else if (isObject(Constructor)) {\n Constructor = Constructor[SPECIES];\n if (Constructor === null) Constructor = undefined;\n }\n if (Constructor === $Array || Constructor === undefined) {\n return un$Slice(O, k, fin);\n }\n }\n result = new (Constructor === undefined ? $Array : Constructor)(max(fin - k, 0));\n for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);\n result.length = n;\n return result;\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.slice.js\n// module id = 385\n// module chunks = 0 1","require('../../modules/es.object.define-property');\nvar path = require('../../internals/path');\n\nvar Object = path.Object;\n\nvar defineProperty = module.exports = function defineProperty(it, key, desc) {\n return Object.defineProperty(it, key, desc);\n};\n\nif (Object.defineProperty.sham) defineProperty.sham = true;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/object/define-property.js\n// module id = 386\n// module chunks = 0 1","var $ = require('../internals/export');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar defineProperty = require('../internals/object-define-property').f;\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\n// eslint-disable-next-line es-x/no-object-defineproperty -- safe\n$({ target: 'Object', stat: true, forced: Object.defineProperty !== defineProperty, sham: !DESCRIPTORS }, {\n defineProperty: defineProperty\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.object.define-property.js\n// module id = 387\n// module chunks = 0 1","const ajax = require('./utils/ajax');\nconst Cache = require('./cache');\n\nfunction AppRouter(AV) {\n this.AV = AV;\n this.lockedUntil = 0;\n Cache.getAsync('serverURLs')\n .then(data => {\n if (this.disabled) return;\n if (!data) return this.lock(0);\n const { serverURLs, lockedUntil } = data;\n this.AV._setServerURLs(serverURLs, false);\n this.lockedUntil = lockedUntil;\n })\n .catch(() => this.lock(0));\n}\n\nAppRouter.prototype.disable = function disable() {\n this.disabled = true;\n};\nAppRouter.prototype.lock = function lock(ttl) {\n this.lockedUntil = Date.now() + ttl;\n};\nAppRouter.prototype.refresh = function refresh() {\n if (this.disabled) return;\n if (Date.now() < this.lockedUntil) return;\n this.lock(10);\n const url = 'https://app-router.com/2/route';\n return ajax({\n method: 'get',\n url,\n query: {\n appId: this.AV.applicationId,\n },\n })\n .then(servers => {\n if (this.disabled) return;\n let ttl = servers.ttl;\n if (!ttl) throw new Error('missing ttl');\n ttl = ttl * 1000;\n const protocal = 'https://';\n const serverURLs = {\n push: protocal + servers.push_server,\n stats: protocal + servers.stats_server,\n engine: protocal + servers.engine_server,\n api: protocal + servers.api_server,\n };\n this.AV._setServerURLs(serverURLs, false);\n this.lock(ttl);\n return Cache.setAsync(\n 'serverURLs',\n {\n serverURLs,\n lockedUntil: this.lockedUntil,\n },\n ttl\n );\n })\n .catch(error => {\n // bypass all errors\n console.warn(`refresh server URLs failed: ${error.message}`);\n this.lock(600);\n });\n};\n\nmodule.exports = AppRouter;\n\n\n\n// WEBPACK FOOTER //\n// ./src/app-router.js","module.exports = require('../../full/symbol');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/symbol/index.js\n// module id = 389\n// module chunks = 0 1","var parent = require('../../actual/symbol');\nrequire('../../modules/esnext.symbol.async-dispose');\nrequire('../../modules/esnext.symbol.dispose');\nrequire('../../modules/esnext.symbol.matcher');\nrequire('../../modules/esnext.symbol.metadata-key');\nrequire('../../modules/esnext.symbol.observable');\n// TODO: Remove from `core-js@4`\nrequire('../../modules/esnext.symbol.metadata');\nrequire('../../modules/esnext.symbol.pattern-match');\nrequire('../../modules/esnext.symbol.replace-all');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/symbol/index.js\n// module id = 390\n// module chunks = 0 1","var parent = require('../../stable/symbol');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/symbol/index.js\n// module id = 391\n// module chunks = 0 1","require('../../modules/es.array.concat');\nrequire('../../modules/es.object.to-string');\nrequire('../../modules/es.symbol');\nrequire('../../modules/es.symbol.async-iterator');\nrequire('../../modules/es.symbol.description');\nrequire('../../modules/es.symbol.has-instance');\nrequire('../../modules/es.symbol.is-concat-spreadable');\nrequire('../../modules/es.symbol.iterator');\nrequire('../../modules/es.symbol.match');\nrequire('../../modules/es.symbol.match-all');\nrequire('../../modules/es.symbol.replace');\nrequire('../../modules/es.symbol.search');\nrequire('../../modules/es.symbol.species');\nrequire('../../modules/es.symbol.split');\nrequire('../../modules/es.symbol.to-primitive');\nrequire('../../modules/es.symbol.to-string-tag');\nrequire('../../modules/es.symbol.unscopables');\nrequire('../../modules/es.json.to-string-tag');\nrequire('../../modules/es.math.to-string-tag');\nrequire('../../modules/es.reflect.to-string-tag');\nvar path = require('../../internals/path');\n\nmodule.exports = path.Symbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/symbol/index.js\n// module id = 392\n// module chunks = 0 1","// TODO: Remove this module from `core-js@4` since it's split to modules listed below\nrequire('../modules/es.symbol.constructor');\nrequire('../modules/es.symbol.for');\nrequire('../modules/es.symbol.key-for');\nrequire('../modules/es.json.stringify');\nrequire('../modules/es.object.get-own-property-symbols');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.js\n// module id = 393\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar global = require('../internals/global');\nvar call = require('../internals/function-call');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar IS_PURE = require('../internals/is-pure');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar NATIVE_SYMBOL = require('../internals/native-symbol');\nvar fails = require('../internals/fails');\nvar hasOwn = require('../internals/has-own-property');\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\nvar anObject = require('../internals/an-object');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toPropertyKey = require('../internals/to-property-key');\nvar $toString = require('../internals/to-string');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar nativeObjectCreate = require('../internals/object-create');\nvar objectKeys = require('../internals/object-keys');\nvar getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');\nvar getOwnPropertyNamesExternal = require('../internals/object-get-own-property-names-external');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar definePropertyModule = require('../internals/object-define-property');\nvar definePropertiesModule = require('../internals/object-define-properties');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar defineBuiltIn = require('../internals/define-built-in');\nvar shared = require('../internals/shared');\nvar sharedKey = require('../internals/shared-key');\nvar hiddenKeys = require('../internals/hidden-keys');\nvar uid = require('../internals/uid');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar wrappedWellKnownSymbolModule = require('../internals/well-known-symbol-wrapped');\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\nvar defineSymbolToPrimitive = require('../internals/symbol-define-to-primitive');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar InternalStateModule = require('../internals/internal-state');\nvar $forEach = require('../internals/array-iteration').forEach;\n\nvar HIDDEN = sharedKey('hidden');\nvar SYMBOL = 'Symbol';\nvar PROTOTYPE = 'prototype';\n\nvar setInternalState = InternalStateModule.set;\nvar getInternalState = InternalStateModule.getterFor(SYMBOL);\n\nvar ObjectPrototype = Object[PROTOTYPE];\nvar $Symbol = global.Symbol;\nvar SymbolPrototype = $Symbol && $Symbol[PROTOTYPE];\nvar TypeError = global.TypeError;\nvar QObject = global.QObject;\nvar nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\nvar nativeDefineProperty = definePropertyModule.f;\nvar nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f;\nvar nativePropertyIsEnumerable = propertyIsEnumerableModule.f;\nvar push = uncurryThis([].push);\n\nvar AllSymbols = shared('symbols');\nvar ObjectPrototypeSymbols = shared('op-symbols');\nvar WellKnownSymbolsStore = shared('wks');\n\n// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173\nvar USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;\n\n// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\nvar setSymbolDescriptor = DESCRIPTORS && fails(function () {\n return nativeObjectCreate(nativeDefineProperty({}, 'a', {\n get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; }\n })).a != 7;\n}) ? function (O, P, Attributes) {\n var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, P);\n if (ObjectPrototypeDescriptor) delete ObjectPrototype[P];\n nativeDefineProperty(O, P, Attributes);\n if (ObjectPrototypeDescriptor && O !== ObjectPrototype) {\n nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor);\n }\n} : nativeDefineProperty;\n\nvar wrap = function (tag, description) {\n var symbol = AllSymbols[tag] = nativeObjectCreate(SymbolPrototype);\n setInternalState(symbol, {\n type: SYMBOL,\n tag: tag,\n description: description\n });\n if (!DESCRIPTORS) symbol.description = description;\n return symbol;\n};\n\nvar $defineProperty = function defineProperty(O, P, Attributes) {\n if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes);\n anObject(O);\n var key = toPropertyKey(P);\n anObject(Attributes);\n if (hasOwn(AllSymbols, key)) {\n if (!Attributes.enumerable) {\n if (!hasOwn(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {}));\n O[HIDDEN][key] = true;\n } else {\n if (hasOwn(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;\n Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) });\n } return setSymbolDescriptor(O, key, Attributes);\n } return nativeDefineProperty(O, key, Attributes);\n};\n\nvar $defineProperties = function defineProperties(O, Properties) {\n anObject(O);\n var properties = toIndexedObject(Properties);\n var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));\n $forEach(keys, function (key) {\n if (!DESCRIPTORS || call($propertyIsEnumerable, properties, key)) $defineProperty(O, key, properties[key]);\n });\n return O;\n};\n\nvar $create = function create(O, Properties) {\n return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties);\n};\n\nvar $propertyIsEnumerable = function propertyIsEnumerable(V) {\n var P = toPropertyKey(V);\n var enumerable = call(nativePropertyIsEnumerable, this, P);\n if (this === ObjectPrototype && hasOwn(AllSymbols, P) && !hasOwn(ObjectPrototypeSymbols, P)) return false;\n return enumerable || !hasOwn(this, P) || !hasOwn(AllSymbols, P) || hasOwn(this, HIDDEN) && this[HIDDEN][P]\n ? enumerable : true;\n};\n\nvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {\n var it = toIndexedObject(O);\n var key = toPropertyKey(P);\n if (it === ObjectPrototype && hasOwn(AllSymbols, key) && !hasOwn(ObjectPrototypeSymbols, key)) return;\n var descriptor = nativeGetOwnPropertyDescriptor(it, key);\n if (descriptor && hasOwn(AllSymbols, key) && !(hasOwn(it, HIDDEN) && it[HIDDEN][key])) {\n descriptor.enumerable = true;\n }\n return descriptor;\n};\n\nvar $getOwnPropertyNames = function getOwnPropertyNames(O) {\n var names = nativeGetOwnPropertyNames(toIndexedObject(O));\n var result = [];\n $forEach(names, function (key) {\n if (!hasOwn(AllSymbols, key) && !hasOwn(hiddenKeys, key)) push(result, key);\n });\n return result;\n};\n\nvar $getOwnPropertySymbols = function (O) {\n var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;\n var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));\n var result = [];\n $forEach(names, function (key) {\n if (hasOwn(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwn(ObjectPrototype, key))) {\n push(result, AllSymbols[key]);\n }\n });\n return result;\n};\n\n// `Symbol` constructor\n// https://tc39.es/ecma262/#sec-symbol-constructor\nif (!NATIVE_SYMBOL) {\n $Symbol = function Symbol() {\n if (isPrototypeOf(SymbolPrototype, this)) throw TypeError('Symbol is not a constructor');\n var description = !arguments.length || arguments[0] === undefined ? undefined : $toString(arguments[0]);\n var tag = uid(description);\n var setter = function (value) {\n if (this === ObjectPrototype) call(setter, ObjectPrototypeSymbols, value);\n if (hasOwn(this, HIDDEN) && hasOwn(this[HIDDEN], tag)) this[HIDDEN][tag] = false;\n setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));\n };\n if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });\n return wrap(tag, description);\n };\n\n SymbolPrototype = $Symbol[PROTOTYPE];\n\n defineBuiltIn(SymbolPrototype, 'toString', function toString() {\n return getInternalState(this).tag;\n });\n\n defineBuiltIn($Symbol, 'withoutSetter', function (description) {\n return wrap(uid(description), description);\n });\n\n propertyIsEnumerableModule.f = $propertyIsEnumerable;\n definePropertyModule.f = $defineProperty;\n definePropertiesModule.f = $defineProperties;\n getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor;\n getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames;\n getOwnPropertySymbolsModule.f = $getOwnPropertySymbols;\n\n wrappedWellKnownSymbolModule.f = function (name) {\n return wrap(wellKnownSymbol(name), name);\n };\n\n if (DESCRIPTORS) {\n // https://github.com/tc39/proposal-Symbol-description\n nativeDefineProperty(SymbolPrototype, 'description', {\n configurable: true,\n get: function description() {\n return getInternalState(this).description;\n }\n });\n if (!IS_PURE) {\n defineBuiltIn(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });\n }\n }\n}\n\n$({ global: true, constructor: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, {\n Symbol: $Symbol\n});\n\n$forEach(objectKeys(WellKnownSymbolsStore), function (name) {\n defineWellKnownSymbol(name);\n});\n\n$({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, {\n useSetter: function () { USE_SETTER = true; },\n useSimple: function () { USE_SETTER = false; }\n});\n\n$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, {\n // `Object.create` method\n // https://tc39.es/ecma262/#sec-object.create\n create: $create,\n // `Object.defineProperty` method\n // https://tc39.es/ecma262/#sec-object.defineproperty\n defineProperty: $defineProperty,\n // `Object.defineProperties` method\n // https://tc39.es/ecma262/#sec-object.defineproperties\n defineProperties: $defineProperties,\n // `Object.getOwnPropertyDescriptor` method\n // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors\n getOwnPropertyDescriptor: $getOwnPropertyDescriptor\n});\n\n$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, {\n // `Object.getOwnPropertyNames` method\n // https://tc39.es/ecma262/#sec-object.getownpropertynames\n getOwnPropertyNames: $getOwnPropertyNames\n});\n\n// `Symbol.prototype[@@toPrimitive]` method\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive\ndefineSymbolToPrimitive();\n\n// `Symbol.prototype[@@toStringTag]` property\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag\nsetToStringTag($Symbol, SYMBOL);\n\nhiddenKeys[HIDDEN] = true;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.constructor.js\n// module id = 394\n// module chunks = 0 1","/* eslint-disable es-x/no-object-getownpropertynames -- safe */\nvar classof = require('../internals/classof-raw');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar $getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar arraySlice = require('../internals/array-slice-simple');\n\nvar windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames\n ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function (it) {\n try {\n return $getOwnPropertyNames(it);\n } catch (error) {\n return arraySlice(windowNames);\n }\n};\n\n// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nmodule.exports.f = function getOwnPropertyNames(it) {\n return windowNames && classof(it) == 'Window'\n ? getWindowNames(it)\n : $getOwnPropertyNames(toIndexedObject(it));\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/internals/object-get-own-property-names-external.js\n// module id = 395\n// module chunks = 0 1","var toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar createProperty = require('../internals/create-property');\n\nvar $Array = Array;\nvar max = Math.max;\n\nmodule.exports = function (O, start, end) {\n var length = lengthOfArrayLike(O);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n var result = $Array(max(fin - k, 0));\n for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]);\n result.length = n;\n return result;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/internals/array-slice-simple.js\n// module id = 396\n// module chunks = 0 1","var $ = require('../internals/export');\nvar getBuiltIn = require('../internals/get-built-in');\nvar hasOwn = require('../internals/has-own-property');\nvar toString = require('../internals/to-string');\nvar shared = require('../internals/shared');\nvar NATIVE_SYMBOL_REGISTRY = require('../internals/native-symbol-registry');\n\nvar StringToSymbolRegistry = shared('string-to-symbol-registry');\nvar SymbolToStringRegistry = shared('symbol-to-string-registry');\n\n// `Symbol.for` method\n// https://tc39.es/ecma262/#sec-symbol.for\n$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, {\n 'for': function (key) {\n var string = toString(key);\n if (hasOwn(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];\n var symbol = getBuiltIn('Symbol')(string);\n StringToSymbolRegistry[string] = symbol;\n SymbolToStringRegistry[symbol] = string;\n return symbol;\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.for.js\n// module id = 397\n// module chunks = 0 1","var $ = require('../internals/export');\nvar hasOwn = require('../internals/has-own-property');\nvar isSymbol = require('../internals/is-symbol');\nvar tryToString = require('../internals/try-to-string');\nvar shared = require('../internals/shared');\nvar NATIVE_SYMBOL_REGISTRY = require('../internals/native-symbol-registry');\n\nvar SymbolToStringRegistry = shared('symbol-to-string-registry');\n\n// `Symbol.keyFor` method\n// https://tc39.es/ecma262/#sec-symbol.keyfor\n$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, {\n keyFor: function keyFor(sym) {\n if (!isSymbol(sym)) throw TypeError(tryToString(sym) + ' is not a symbol');\n if (hasOwn(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.key-for.js\n// module id = 398\n// module chunks = 0 1","var $ = require('../internals/export');\nvar NATIVE_SYMBOL = require('../internals/native-symbol');\nvar fails = require('../internals/fails');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar toObject = require('../internals/to-object');\n\n// V8 ~ Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives\n// https://bugs.chromium.org/p/v8/issues/detail?id=3443\nvar FORCED = !NATIVE_SYMBOL || fails(function () { getOwnPropertySymbolsModule.f(1); });\n\n// `Object.getOwnPropertySymbols` method\n// https://tc39.es/ecma262/#sec-object.getownpropertysymbols\n$({ target: 'Object', stat: true, forced: FORCED }, {\n getOwnPropertySymbols: function getOwnPropertySymbols(it) {\n var $getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return $getOwnPropertySymbols ? $getOwnPropertySymbols(toObject(it)) : [];\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.object.get-own-property-symbols.js\n// module id = 399\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.asyncIterator` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.asynciterator\ndefineWellKnownSymbol('asyncIterator');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.async-iterator.js\n// module id = 400\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.hasInstance` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.hasinstance\ndefineWellKnownSymbol('hasInstance');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.has-instance.js\n// module id = 402\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.isConcatSpreadable` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.isconcatspreadable\ndefineWellKnownSymbol('isConcatSpreadable');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.is-concat-spreadable.js\n// module id = 403\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.match` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.match\ndefineWellKnownSymbol('match');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.match.js\n// module id = 404\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.matchAll` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.matchall\ndefineWellKnownSymbol('matchAll');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.match-all.js\n// module id = 405\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.replace` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.replace\ndefineWellKnownSymbol('replace');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.replace.js\n// module id = 406\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.search` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.search\ndefineWellKnownSymbol('search');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.search.js\n// module id = 407\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.species` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.species\ndefineWellKnownSymbol('species');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.species.js\n// module id = 408\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.split` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.split\ndefineWellKnownSymbol('split');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.split.js\n// module id = 409\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\nvar defineSymbolToPrimitive = require('../internals/symbol-define-to-primitive');\n\n// `Symbol.toPrimitive` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.toprimitive\ndefineWellKnownSymbol('toPrimitive');\n\n// `Symbol.prototype[@@toPrimitive]` method\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive\ndefineSymbolToPrimitive();\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.to-primitive.js\n// module id = 410\n// module chunks = 0 1","var getBuiltIn = require('../internals/get-built-in');\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\nvar setToStringTag = require('../internals/set-to-string-tag');\n\n// `Symbol.toStringTag` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.tostringtag\ndefineWellKnownSymbol('toStringTag');\n\n// `Symbol.prototype[@@toStringTag]` property\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag\nsetToStringTag(getBuiltIn('Symbol'), 'Symbol');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.to-string-tag.js\n// module id = 411\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.unscopables` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.unscopables\ndefineWellKnownSymbol('unscopables');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.unscopables.js\n// module id = 412\n// module chunks = 0 1","var global = require('../internals/global');\nvar setToStringTag = require('../internals/set-to-string-tag');\n\n// JSON[@@toStringTag] property\n// https://tc39.es/ecma262/#sec-json-@@tostringtag\nsetToStringTag(global.JSON, 'JSON', true);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.json.to-string-tag.js\n// module id = 413\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.asyncDispose` well-known symbol\n// https://github.com/tc39/proposal-using-statement\ndefineWellKnownSymbol('asyncDispose');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.async-dispose.js\n// module id = 416\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.dispose` well-known symbol\n// https://github.com/tc39/proposal-using-statement\ndefineWellKnownSymbol('dispose');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.dispose.js\n// module id = 417\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.matcher` well-known symbol\n// https://github.com/tc39/proposal-pattern-matching\ndefineWellKnownSymbol('matcher');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.matcher.js\n// module id = 418\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.metadataKey` well-known symbol\n// https://github.com/tc39/proposal-decorator-metadata\ndefineWellKnownSymbol('metadataKey');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.metadata-key.js\n// module id = 419\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.observable` well-known symbol\n// https://github.com/tc39/proposal-observable\ndefineWellKnownSymbol('observable');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.observable.js\n// module id = 420\n// module chunks = 0 1","// TODO: Remove from `core-js@4`\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.metadata` well-known symbol\n// https://github.com/tc39/proposal-decorators\ndefineWellKnownSymbol('metadata');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.metadata.js\n// module id = 421\n// module chunks = 0 1","// TODO: remove from `core-js@4`\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.patternMatch` well-known symbol\n// https://github.com/tc39/proposal-pattern-matching\ndefineWellKnownSymbol('patternMatch');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.pattern-match.js\n// module id = 422\n// module chunks = 0 1","// TODO: remove from `core-js@4`\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\ndefineWellKnownSymbol('replaceAll');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.replace-all.js\n// module id = 423\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/symbol/iterator\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/symbol/iterator.js\n// module id = 424\n// module chunks = 0 1","module.exports = require('../../full/symbol/iterator');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/symbol/iterator.js\n// module id = 425\n// module chunks = 0 1","var parent = require('../../actual/symbol/iterator');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/symbol/iterator.js\n// module id = 426\n// module chunks = 0 1","var parent = require('../../stable/symbol/iterator');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/symbol/iterator.js\n// module id = 427\n// module chunks = 0 1","var parent = require('../../es/symbol/iterator');\nrequire('../../modules/web.dom-collections.iterator');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/symbol/iterator.js\n// module id = 428\n// module chunks = 0 1","require('../../modules/es.array.iterator');\nrequire('../../modules/es.object.to-string');\nrequire('../../modules/es.string.iterator');\nrequire('../../modules/es.symbol.iterator');\nvar WrappedWellKnownSymbolModule = require('../../internals/well-known-symbol-wrapped');\n\nmodule.exports = WrappedWellKnownSymbolModule.f('iterator');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/symbol/iterator.js\n// module id = 429\n// module chunks = 0 1","module.exports = require(\"core-js-pure/stable/instance/filter\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js-stable/instance/filter.js\n// module id = 430\n// module chunks = 0 1","var parent = require('../../es/instance/filter');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/instance/filter.js\n// module id = 431\n// module chunks = 0 1","var isPrototypeOf = require('../../internals/object-is-prototype-of');\nvar method = require('../array/virtual/filter');\n\nvar ArrayPrototype = Array.prototype;\n\nmodule.exports = function (it) {\n var own = it.filter;\n return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.filter) ? method : own;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/instance/filter.js\n// module id = 432\n// module chunks = 0 1","require('../../../modules/es.array.filter');\nvar entryVirtual = require('../../../internals/entry-virtual');\n\nmodule.exports = entryVirtual('Array').filter;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/virtual/filter.js\n// module id = 433\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar $filter = require('../internals/array-iteration').filter;\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter');\n\n// `Array.prototype.filter` method\n// https://tc39.es/ecma262/#sec-array.prototype.filter\n// with adding support of @@species\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {\n filter: function filter(callbackfn /* , thisArg */) {\n return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.filter.js\n// module id = 434\n// module chunks = 0 1","// Copyright (c) 2015-2017 David M. Lee, II\n'use strict';\n\n/**\n * Local reference to TimeoutError\n * @private\n */\nvar TimeoutError;\n\n/**\n * Rejects a promise with a {@link TimeoutError} if it does not settle within\n * the specified timeout.\n *\n * @param {Promise} promise The promise.\n * @param {number} timeoutMillis Number of milliseconds to wait on settling.\n * @returns {Promise} Either resolves/rejects with `promise`, or rejects with\n * `TimeoutError`, whichever settles first.\n */\nvar timeout = module.exports.timeout = function(promise, timeoutMillis) {\n var error = new TimeoutError(),\n timeout;\n\n return Promise.race([\n promise,\n new Promise(function(resolve, reject) {\n timeout = setTimeout(function() {\n reject(error);\n }, timeoutMillis);\n }),\n ]).then(function(v) {\n clearTimeout(timeout);\n return v;\n }, function(err) {\n clearTimeout(timeout);\n throw err;\n });\n};\n\n/**\n * Exception indicating that the timeout expired.\n */\nTimeoutError = module.exports.TimeoutError = function() {\n Error.call(this)\n this.stack = Error().stack\n this.message = 'Timeout';\n};\n\nTimeoutError.prototype = Object.create(Error.prototype);\nTimeoutError.prototype.name = \"TimeoutError\";\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/promise-timeout/index.js\n// module id = 435\n// module chunks = 0 1","var _ = require('underscore');\n\nmodule.exports = function(AV) {\n var eventSplitter = /\\s+/;\n var slice = Array.prototype.slice;\n\n /**\n * @class\n *\n *AV.Events is a fork of Backbone's Events module, provided for your\n * convenience.
\n *\n *A module that can be mixed in to any object in order to provide\n * it with custom events. You may bind callback functions to an event\n * with `on`, or remove these functions with `off`.\n * Triggering an event fires all callbacks in the order that `on` was\n * called.\n *\n * @private\n * @example\n * var object = {};\n * _.extend(object, AV.Events);\n * object.on('expand', function(){ alert('expanded'); });\n * object.trigger('expand');
\n *\n */\n AV.Events = {\n /**\n * Bind one or more space separated events, `events`, to a `callback`\n * function. Passing `\"all\"` will bind the callback to all events fired.\n */\n on: function(events, callback, context) {\n var calls, event, node, tail, list;\n if (!callback) {\n return this;\n }\n events = events.split(eventSplitter);\n calls = this._callbacks || (this._callbacks = {});\n\n // Create an immutable callback list, allowing traversal during\n // modification. The tail is an empty object that will always be used\n // as the next node.\n event = events.shift();\n while (event) {\n list = calls[event];\n node = list ? list.tail : {};\n node.next = tail = {};\n node.context = context;\n node.callback = callback;\n calls[event] = { tail: tail, next: list ? list.next : node };\n event = events.shift();\n }\n\n return this;\n },\n\n /**\n * Remove one or many callbacks. If `context` is null, removes all callbacks\n * with that function. If `callback` is null, removes all callbacks for the\n * event. If `events` is null, removes all bound callbacks for all events.\n */\n off: function(events, callback, context) {\n var event, calls, node, tail, cb, ctx;\n\n // No events, or removing *all* events.\n if (!(calls = this._callbacks)) {\n return;\n }\n if (!(events || callback || context)) {\n delete this._callbacks;\n return this;\n }\n\n // Loop through the listed events and contexts, splicing them out of the\n // linked list of callbacks if appropriate.\n events = events ? events.split(eventSplitter) : _.keys(calls);\n event = events.shift();\n while (event) {\n node = calls[event];\n delete calls[event];\n if (!node || !(callback || context)) {\n continue;\n }\n // Create a new list, omitting the indicated callbacks.\n tail = node.tail;\n node = node.next;\n while (node !== tail) {\n cb = node.callback;\n ctx = node.context;\n if ((callback && cb !== callback) || (context && ctx !== context)) {\n this.on(event, cb, ctx);\n }\n node = node.next;\n }\n event = events.shift();\n }\n\n return this;\n },\n\n /**\n * Trigger one or many events, firing all bound callbacks. Callbacks are\n * passed the same arguments as `trigger` is, apart from the event name\n * (unless you're listening on `\"all\"`, which will cause your callback to\n * receive the true name of the event as the first argument).\n */\n trigger: function(events) {\n var event, node, calls, tail, args, all, rest;\n if (!(calls = this._callbacks)) {\n return this;\n }\n all = calls.all;\n events = events.split(eventSplitter);\n rest = slice.call(arguments, 1);\n\n // For each event, walk through the linked list of callbacks twice,\n // first to trigger the event, then to trigger any `\"all\"` callbacks.\n event = events.shift();\n while (event) {\n node = calls[event];\n if (node) {\n tail = node.tail;\n while ((node = node.next) !== tail) {\n node.callback.apply(node.context || this, rest);\n }\n }\n node = all;\n if (node) {\n tail = node.tail;\n args = [event].concat(rest);\n while ((node = node.next) !== tail) {\n node.callback.apply(node.context || this, args);\n }\n }\n event = events.shift();\n }\n\n return this;\n },\n };\n\n /**\n * @function\n */\n AV.Events.bind = AV.Events.on;\n\n /**\n * @function\n */\n AV.Events.unbind = AV.Events.off;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/event.js","var _ = require('underscore');\n\n/*global navigator: false */\nmodule.exports = function(AV) {\n /**\n * Creates a new GeoPoint with any of the following forms:Represents a latitude / longitude point that may be associated\n * with a key in a AVObject or used as a reference point for geo queries.\n * This allows proximity-based queries on the key.
\n *\n *Only one key in a class may contain a GeoPoint.
\n *\n *Example:
\n * var point = new AV.GeoPoint(30.0, -20.0);\n * var object = new AV.Object(\"PlaceObject\");\n * object.set(\"location\", point);\n * object.save();\n */\n AV.GeoPoint = function(arg1, arg2) {\n if (_.isArray(arg1)) {\n AV.GeoPoint._validate(arg1[0], arg1[1]);\n this.latitude = arg1[0];\n this.longitude = arg1[1];\n } else if (_.isObject(arg1)) {\n AV.GeoPoint._validate(arg1.latitude, arg1.longitude);\n this.latitude = arg1.latitude;\n this.longitude = arg1.longitude;\n } else if (_.isNumber(arg1) && _.isNumber(arg2)) {\n AV.GeoPoint._validate(arg1, arg2);\n this.latitude = arg1;\n this.longitude = arg2;\n } else {\n this.latitude = 0;\n this.longitude = 0;\n }\n\n // Add properties so that anyone using Webkit or Mozilla will get an error\n // if they try to set values that are out of bounds.\n var self = this;\n if (this.__defineGetter__ && this.__defineSetter__) {\n // Use _latitude and _longitude to actually store the values, and add\n // getters and setters for latitude and longitude.\n this._latitude = this.latitude;\n this._longitude = this.longitude;\n this.__defineGetter__('latitude', function() {\n return self._latitude;\n });\n this.__defineGetter__('longitude', function() {\n return self._longitude;\n });\n this.__defineSetter__('latitude', function(val) {\n AV.GeoPoint._validate(val, self.longitude);\n self._latitude = val;\n });\n this.__defineSetter__('longitude', function(val) {\n AV.GeoPoint._validate(self.latitude, val);\n self._longitude = val;\n });\n }\n };\n\n /**\n * @lends AV.GeoPoint.prototype\n * @property {float} latitude North-south portion of the coordinate, in range\n * [-90, 90]. Throws an exception if set out of range in a modern browser.\n * @property {float} longitude East-west portion of the coordinate, in range\n * [-180, 180]. Throws if set out of range in a modern browser.\n */\n\n /**\n * Throws an exception if the given lat-long is out of bounds.\n * @private\n */\n AV.GeoPoint._validate = function(latitude, longitude) {\n if (latitude < -90.0) {\n throw new Error('AV.GeoPoint latitude ' + latitude + ' < -90.0.');\n }\n if (latitude > 90.0) {\n throw new Error('AV.GeoPoint latitude ' + latitude + ' > 90.0.');\n }\n if (longitude < -180.0) {\n throw new Error('AV.GeoPoint longitude ' + longitude + ' < -180.0.');\n }\n if (longitude > 180.0) {\n throw new Error('AV.GeoPoint longitude ' + longitude + ' > 180.0.');\n }\n };\n\n /**\n * Creates a GeoPoint with the user's current location, if available.\n * @return {Promise.
An ACL, or Access Control List can be added to any\n * AV.Object
to restrict access to only a subset of users\n * of your application.
object.set(\"foo\", \"bar\")
\n * is an example of a AV.Op.Set. Calling object.unset(\"foo\")
\n * is a AV.Op.Unset. These operations are stored in a AV.Object and\n * sent to the server as part of object.save()
operations.\n * Instances of AV.Op should be immutable.\n *\n * You should not create subclasses of AV.Op or instantiate AV.Op\n * directly.\n */\n AV.Op = function() {\n this._initialize.apply(this, arguments);\n };\n\n _.extend(\n AV.Op.prototype,\n /** @lends AV.Op.prototype */ {\n _initialize: function() {},\n }\n );\n\n _.extend(AV.Op, {\n /**\n * To create a new Op, call AV.Op._extend();\n * @private\n */\n _extend: AV._extend,\n\n // A map of __op string to decoder function.\n _opDecoderMap: {},\n\n /**\n * Registers a function to convert a json object with an __op field into an\n * instance of a subclass of AV.Op.\n * @private\n */\n _registerDecoder: function(opName, decoder) {\n AV.Op._opDecoderMap[opName] = decoder;\n },\n\n /**\n * Converts a json object into an instance of a subclass of AV.Op.\n * @private\n */\n _decode: function(json) {\n var decoder = AV.Op._opDecoderMap[json.__op];\n if (decoder) {\n return decoder(json);\n } else {\n return undefined;\n }\n },\n });\n\n /*\n * Add a handler for Batch ops.\n */\n AV.Op._registerDecoder('Batch', function(json) {\n var op = null;\n AV._arrayEach(json.ops, function(nextOp) {\n nextOp = AV.Op._decode(nextOp);\n op = nextOp._mergeWithPrevious(op);\n });\n return op;\n });\n\n /**\n * @private\n * @class\n * A Set operation indicates that either the field was changed using\n * AV.Object.set, or it is a mutable container that was detected as being\n * changed.\n */\n AV.Op.Set = AV.Op._extend(\n /** @lends AV.Op.Set.prototype */ {\n _initialize: function(value) {\n this._value = value;\n },\n\n /**\n * Returns the new value of this field after the set.\n */\n value: function() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return AV._encode(this.value());\n },\n\n _mergeWithPrevious: function(previous) {\n return this;\n },\n\n _estimate: function(oldValue) {\n return this.value();\n },\n }\n );\n\n /**\n * A sentinel value that is returned by AV.Op.Unset._estimate to\n * indicate the field should be deleted. Basically, if you find _UNSET as a\n * value in your object, you should remove that key.\n */\n AV.Op._UNSET = {};\n\n /**\n * @private\n * @class\n * An Unset operation indicates that this field has been deleted from the\n * object.\n */\n AV.Op.Unset = AV.Op._extend(\n /** @lends AV.Op.Unset.prototype */ {\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Delete' };\n },\n\n _mergeWithPrevious: function(previous) {\n return this;\n },\n\n _estimate: function(oldValue) {\n return AV.Op._UNSET;\n },\n }\n );\n\n AV.Op._registerDecoder('Delete', function(json) {\n return new AV.Op.Unset();\n });\n\n /**\n * @private\n * @class\n * An Increment is an atomic operation where the numeric value for the field\n * will be increased by a given amount.\n */\n AV.Op.Increment = AV.Op._extend(\n /** @lends AV.Op.Increment.prototype */ {\n _initialize: function(amount) {\n this._amount = amount;\n },\n\n /**\n * Returns the amount to increment by.\n * @return {Number} the amount to increment by.\n */\n amount: function() {\n return this._amount;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Increment', amount: this._amount };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.amount());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() + this.amount());\n } else if (previous instanceof AV.Op.Increment) {\n return new AV.Op.Increment(this.amount() + previous.amount());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return this.amount();\n }\n return oldValue + this.amount();\n },\n }\n );\n\n AV.Op._registerDecoder('Increment', function(json) {\n return new AV.Op.Increment(json.amount);\n });\n\n /**\n * @private\n * @class\n * BitAnd is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n AV.Op.BitAnd = AV.Op._extend(\n /** @lends AV.Op.BitAnd.prototype */ {\n _initialize(value) {\n this._value = value;\n },\n\n value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON() {\n return { __op: 'BitAnd', value: this.value() };\n },\n\n _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(0);\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() & this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate(oldValue) {\n return oldValue & this.value();\n },\n }\n );\n\n AV.Op._registerDecoder('BitAnd', function(json) {\n return new AV.Op.BitAnd(json.value);\n });\n\n /**\n * @private\n * @class\n * BitOr is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n AV.Op.BitOr = AV.Op._extend(\n /** @lends AV.Op.BitOr.prototype */ {\n _initialize(value) {\n this._value = value;\n },\n\n value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON() {\n return { __op: 'BitOr', value: this.value() };\n },\n\n _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.value());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() | this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate(oldValue) {\n return oldValue | this.value();\n },\n }\n );\n\n AV.Op._registerDecoder('BitOr', function(json) {\n return new AV.Op.BitOr(json.value);\n });\n\n /**\n * @private\n * @class\n * BitXor is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n AV.Op.BitXor = AV.Op._extend(\n /** @lends AV.Op.BitXor.prototype */ {\n _initialize(value) {\n this._value = value;\n },\n\n value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON() {\n return { __op: 'BitXor', value: this.value() };\n },\n\n _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.value());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() ^ this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate(oldValue) {\n return oldValue ^ this.value();\n },\n }\n );\n\n AV.Op._registerDecoder('BitXor', function(json) {\n return new AV.Op.BitXor(json.value);\n });\n\n /**\n * @private\n * @class\n * Add is an atomic operation where the given objects will be appended to the\n * array that is stored in this field.\n */\n AV.Op.Add = AV.Op._extend(\n /** @lends AV.Op.Add.prototype */ {\n _initialize: function(objects) {\n this._objects = objects;\n },\n\n /**\n * Returns the objects to be added to the array.\n * @return {Array} The objects to be added to the array.\n */\n objects: function() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Add', objects: AV._encode(this.objects()) };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.objects());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.Add) {\n return new AV.Op.Add(previous.objects().concat(this.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return _.clone(this.objects());\n } else {\n return oldValue.concat(this.objects());\n }\n },\n }\n );\n\n AV.Op._registerDecoder('Add', function(json) {\n return new AV.Op.Add(AV._decode(json.objects));\n });\n\n /**\n * @private\n * @class\n * AddUnique is an atomic operation where the given items will be appended to\n * the array that is stored in this field only if they were not already\n * present in the array.\n */\n AV.Op.AddUnique = AV.Op._extend(\n /** @lends AV.Op.AddUnique.prototype */ {\n _initialize: function(objects) {\n this._objects = _.uniq(objects);\n },\n\n /**\n * Returns the objects to be added to the array.\n * @return {Array} The objects to be added to the array.\n */\n objects: function() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'AddUnique', objects: AV._encode(this.objects()) };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.objects());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.AddUnique) {\n return new AV.Op.AddUnique(this._estimate(previous.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return _.clone(this.objects());\n } else {\n // We can't just take the _.uniq(_.union(...)) of oldValue and\n // this.objects, because the uniqueness may not apply to oldValue\n // (especially if the oldValue was set via .set())\n var newValue = _.clone(oldValue);\n AV._arrayEach(this.objects(), function(obj) {\n if (obj instanceof AV.Object && obj.id) {\n var matchingObj = _.find(newValue, function(anObj) {\n return anObj instanceof AV.Object && anObj.id === obj.id;\n });\n if (!matchingObj) {\n newValue.push(obj);\n } else {\n var index = _.indexOf(newValue, matchingObj);\n newValue[index] = obj;\n }\n } else if (!_.contains(newValue, obj)) {\n newValue.push(obj);\n }\n });\n return newValue;\n }\n },\n }\n );\n\n AV.Op._registerDecoder('AddUnique', function(json) {\n return new AV.Op.AddUnique(AV._decode(json.objects));\n });\n\n /**\n * @private\n * @class\n * Remove is an atomic operation where the given objects will be removed from\n * the array that is stored in this field.\n */\n AV.Op.Remove = AV.Op._extend(\n /** @lends AV.Op.Remove.prototype */ {\n _initialize: function(objects) {\n this._objects = _.uniq(objects);\n },\n\n /**\n * Returns the objects to be removed from the array.\n * @return {Array} The objects to be removed from the array.\n */\n objects: function() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Remove', objects: AV._encode(this.objects()) };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return previous;\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.Remove) {\n return new AV.Op.Remove(_.union(previous.objects(), this.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return [];\n } else {\n var newValue = _.difference(oldValue, this.objects());\n // If there are saved AV Objects being removed, also remove them.\n AV._arrayEach(this.objects(), function(obj) {\n if (obj instanceof AV.Object && obj.id) {\n newValue = _.reject(newValue, function(other) {\n return other instanceof AV.Object && other.id === obj.id;\n });\n }\n });\n return newValue;\n }\n },\n }\n );\n\n AV.Op._registerDecoder('Remove', function(json) {\n return new AV.Op.Remove(AV._decode(json.objects));\n });\n\n /**\n * @private\n * @class\n * A Relation operation indicates that the field is an instance of\n * AV.Relation, and objects are being added to, or removed from, that\n * relation.\n */\n AV.Op.Relation = AV.Op._extend(\n /** @lends AV.Op.Relation.prototype */ {\n _initialize: function(adds, removes) {\n this._targetClassName = null;\n\n var self = this;\n\n var pointerToId = function(object) {\n if (object instanceof AV.Object) {\n if (!object.id) {\n throw new Error(\n \"You can't add an unsaved AV.Object to a relation.\"\n );\n }\n if (!self._targetClassName) {\n self._targetClassName = object.className;\n }\n if (self._targetClassName !== object.className) {\n throw new Error(\n 'Tried to create a AV.Relation with 2 different types: ' +\n self._targetClassName +\n ' and ' +\n object.className +\n '.'\n );\n }\n return object.id;\n }\n return object;\n };\n\n this.relationsToAdd = _.uniq(_.map(adds, pointerToId));\n this.relationsToRemove = _.uniq(_.map(removes, pointerToId));\n },\n\n /**\n * Returns an array of unfetched AV.Object that are being added to the\n * relation.\n * @return {Array}\n */\n added: function() {\n var self = this;\n return _.map(this.relationsToAdd, function(objectId) {\n var object = AV.Object._create(self._targetClassName);\n object.id = objectId;\n return object;\n });\n },\n\n /**\n * Returns an array of unfetched AV.Object that are being removed from\n * the relation.\n * @return {Array}\n */\n removed: function() {\n var self = this;\n return _.map(this.relationsToRemove, function(objectId) {\n var object = AV.Object._create(self._targetClassName);\n object.id = objectId;\n return object;\n });\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n var adds = null;\n var removes = null;\n var self = this;\n var idToPointer = function(id) {\n return {\n __type: 'Pointer',\n className: self._targetClassName,\n objectId: id,\n };\n };\n var pointers = null;\n if (this.relationsToAdd.length > 0) {\n pointers = _.map(this.relationsToAdd, idToPointer);\n adds = { __op: 'AddRelation', objects: pointers };\n }\n\n if (this.relationsToRemove.length > 0) {\n pointers = _.map(this.relationsToRemove, idToPointer);\n removes = { __op: 'RemoveRelation', objects: pointers };\n }\n\n if (adds && removes) {\n return { __op: 'Batch', ops: [adds, removes] };\n }\n\n return adds || removes || {};\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n throw new Error(\"You can't modify a relation after deleting it.\");\n } else if (previous instanceof AV.Op.Relation) {\n if (\n previous._targetClassName &&\n previous._targetClassName !== this._targetClassName\n ) {\n throw new Error(\n 'Related object must be of class ' +\n previous._targetClassName +\n ', but ' +\n this._targetClassName +\n ' was passed in.'\n );\n }\n var newAdd = _.union(\n _.difference(previous.relationsToAdd, this.relationsToRemove),\n this.relationsToAdd\n );\n var newRemove = _.union(\n _.difference(previous.relationsToRemove, this.relationsToAdd),\n this.relationsToRemove\n );\n\n var newRelation = new AV.Op.Relation(newAdd, newRemove);\n newRelation._targetClassName = this._targetClassName;\n return newRelation;\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue, object, key) {\n if (!oldValue) {\n var relation = new AV.Relation(object, key);\n relation.targetClassName = this._targetClassName;\n } else if (oldValue instanceof AV.Relation) {\n if (this._targetClassName) {\n if (oldValue.targetClassName) {\n if (oldValue.targetClassName !== this._targetClassName) {\n throw new Error(\n 'Related object must be a ' +\n oldValue.targetClassName +\n ', but a ' +\n this._targetClassName +\n ' was passed in.'\n );\n }\n } else {\n oldValue.targetClassName = this._targetClassName;\n }\n }\n return oldValue;\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n }\n );\n\n AV.Op._registerDecoder('AddRelation', function(json) {\n return new AV.Op.Relation(AV._decode(json.objects), []);\n });\n AV.Op._registerDecoder('RemoveRelation', function(json) {\n return new AV.Op.Relation([], AV._decode(json.objects));\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/op.js","var parent = require('../../es/instance/find');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/instance/find.js\n// module id = 440\n// module chunks = 0 1","var isPrototypeOf = require('../../internals/object-is-prototype-of');\nvar method = require('../array/virtual/find');\n\nvar ArrayPrototype = Array.prototype;\n\nmodule.exports = function (it) {\n var own = it.find;\n return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.find) ? method : own;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/instance/find.js\n// module id = 441\n// module chunks = 0 1","require('../../../modules/es.array.find');\nvar entryVirtual = require('../../../internals/entry-virtual');\n\nmodule.exports = entryVirtual('Array').find;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/virtual/find.js\n// module id = 442\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar $find = require('../internals/array-iteration').find;\nvar addToUnscopables = require('../internals/add-to-unscopables');\n\nvar FIND = 'find';\nvar SKIPS_HOLES = true;\n\n// Shouldn't skip holes\nif (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });\n\n// `Array.prototype.find` method\n// https://tc39.es/ecma262/#sec-array.prototype.find\n$({ target: 'Array', proto: true, forced: SKIPS_HOLES }, {\n find: function find(callbackfn /* , that = undefined */) {\n return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables(FIND);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.find.js\n// module id = 443\n// module chunks = 0 1","var _ = require('underscore');\n\nmodule.exports = function(AV) {\n /**\n * Creates a new Relation for the given parent object and key. This\n * constructor should rarely be used directly, but rather created by\n * {@link AV.Object#relation}.\n * @param {AV.Object} parent The parent of this relation.\n * @param {String} key The key for this relation on the parent.\n * @see AV.Object#relation\n * @class\n *\n * \n * A class that is used to access all of the children of a many-to-many\n * relationship. Each instance of AV.Relation is associated with a\n * particular parent object and key.\n *
\n */\n AV.Relation = function(parent, key) {\n if (!_.isString(key)) {\n throw new TypeError('key must be a string');\n }\n this.parent = parent;\n this.key = key;\n this.targetClassName = null;\n };\n\n /**\n * Creates a query that can be used to query the parent objects in this relation.\n * @param {String} parentClass The parent class or name.\n * @param {String} relationKey The relation field key in parent.\n * @param {AV.Object} child The child object.\n * @return {AV.Query}\n */\n AV.Relation.reverseQuery = function(parentClass, relationKey, child) {\n var query = new AV.Query(parentClass);\n query.equalTo(relationKey, child._toPointer());\n return query;\n };\n\n _.extend(\n AV.Relation.prototype,\n /** @lends AV.Relation.prototype */ {\n /**\n * Makes sure that this relation has the right parent and key.\n * @private\n */\n _ensureParentAndKey: function(parent, key) {\n this.parent = this.parent || parent;\n this.key = this.key || key;\n if (this.parent !== parent) {\n throw new Error(\n 'Internal Error. Relation retrieved from two different Objects.'\n );\n }\n if (this.key !== key) {\n throw new Error(\n 'Internal Error. Relation retrieved from two different keys.'\n );\n }\n },\n\n /**\n * Adds a AV.Object or an array of AV.Objects to the relation.\n * @param {AV.Object|AV.Object[]} objects The item or items to add.\n */\n add: function(objects) {\n if (!_.isArray(objects)) {\n objects = [objects];\n }\n\n var change = new AV.Op.Relation(objects, []);\n this.parent.set(this.key, change);\n this.targetClassName = change._targetClassName;\n },\n\n /**\n * Removes a AV.Object or an array of AV.Objects from this relation.\n * @param {AV.Object|AV.Object[]} objects The item or items to remove.\n */\n remove: function(objects) {\n if (!_.isArray(objects)) {\n objects = [objects];\n }\n\n var change = new AV.Op.Relation([], objects);\n this.parent.set(this.key, change);\n this.targetClassName = change._targetClassName;\n },\n\n /**\n * Returns a JSON version of the object suitable for saving to disk.\n * @return {Object}\n */\n toJSON: function() {\n return { __type: 'Relation', className: this.targetClassName };\n },\n\n /**\n * Returns a AV.Query that is limited to objects in this\n * relation.\n * @return {AV.Query}\n */\n query: function() {\n var targetClass;\n var query;\n if (!this.targetClassName) {\n targetClass = AV.Object._getSubclass(this.parent.className);\n query = new AV.Query(targetClass);\n query._defaultParams.redirectClassNameForKey = this.key;\n } else {\n targetClass = AV.Object._getSubclass(this.targetClassName);\n query = new AV.Query(targetClass);\n }\n query._addCondition('$relatedTo', 'object', this.parent._toPointer());\n query._addCondition('$relatedTo', 'key', this.key);\n\n return query;\n },\n }\n );\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/relation.js","const _ = require('underscore');\nconst cos = require('./uploader/cos');\nconst qiniu = require('./uploader/qiniu');\nconst s3 = require('./uploader/s3');\nconst AVError = require('./error');\nconst { request, _request: AVRequest } = require('./request');\nconst { tap, transformFetchOptions } = require('./utils');\nconst debug = require('debug')('leancloud:file');\nconst parseBase64 = require('./utils/parse-base64');\n\nmodule.exports = function(AV) {\n // port from browserify path module\n // since react-native packager won't shim node modules.\n const extname = path => {\n if (!_.isString(path)) return '';\n return path.match(\n /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/\n )[4];\n };\n\n const b64Digit = number => {\n if (number < 26) {\n return String.fromCharCode(65 + number);\n }\n if (number < 52) {\n return String.fromCharCode(97 + (number - 26));\n }\n if (number < 62) {\n return String.fromCharCode(48 + (number - 52));\n }\n if (number === 62) {\n return '+';\n }\n if (number === 63) {\n return '/';\n }\n throw new Error('Tried to encode large digit ' + number + ' in base64.');\n };\n\n var encodeBase64 = function(array) {\n var chunks = [];\n chunks.length = Math.ceil(array.length / 3);\n _.times(chunks.length, function(i) {\n var b1 = array[i * 3];\n var b2 = array[i * 3 + 1] || 0;\n var b3 = array[i * 3 + 2] || 0;\n\n var has2 = i * 3 + 1 < array.length;\n var has3 = i * 3 + 2 < array.length;\n\n chunks[i] = [\n b64Digit((b1 >> 2) & 0x3f),\n b64Digit(((b1 << 4) & 0x30) | ((b2 >> 4) & 0x0f)),\n has2 ? b64Digit(((b2 << 2) & 0x3c) | ((b3 >> 6) & 0x03)) : '=',\n has3 ? b64Digit(b3 & 0x3f) : '=',\n ].join('');\n });\n return chunks.join('');\n };\n\n /**\n * An AV.File is a local representation of a file that is saved to the AV\n * cloud.\n * @param name {String} The file's name. This will change to a unique value\n * once the file has finished saving.\n * @param data {Array} The data for the file, as either:\n * 1. an Array of byte value Numbers, or\n * 2. an Object like { base64: \"...\" } with a base64-encoded String.\n * 3. a Blob(File) selected with a file upload control in a browser.\n * 4. an Object like { blob: {uri: \"...\"} } that mimics Blob\n * in some non-browser environments such as React Native.\n * 5. a Buffer in Node.js runtime.\n * 6. a Stream in Node.js runtime.\n *\n * For example:\n * var fileUploadControl = $(\"#profilePhotoFileUpload\")[0];\n * if (fileUploadControl.files.length > 0) {\n * var file = fileUploadControl.files[0];\n * var name = \"photo.jpg\";\n * var file = new AV.File(name, file);\n * file.save().then(function() {\n * // The file has been saved to AV.\n * }, function(error) {\n * // The file either could not be read, or could not be saved to AV.\n * });\n * }\n *\n * @class\n * @param [mimeType] {String} Content-Type header to use for the file. If\n * this is omitted, the content type will be inferred from the name's\n * extension.\n */\n AV.File = function(name, data, mimeType) {\n this.attributes = {\n name,\n url: '',\n metaData: {},\n // 用来存储转换后要上传的 base64 String\n base64: '',\n };\n\n if (_.isString(data)) {\n throw new TypeError(\n 'Creating an AV.File from a String is not yet supported.'\n );\n }\n if (_.isArray(data)) {\n this.attributes.metaData.size = data.length;\n data = { base64: encodeBase64(data) };\n }\n\n this._extName = '';\n this._data = data;\n this._uploadHeaders = {};\n\n if (data && data.blob && typeof data.blob.uri === 'string') {\n this._extName = extname(data.blob.uri);\n }\n\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n if (data.size) {\n this.attributes.metaData.size = data.size;\n }\n if (data.name) {\n this._extName = extname(data.name);\n }\n }\n\n\n let owner;\n if (data && data.owner) {\n owner = data.owner;\n } else if (!AV._config.disableCurrentUser) {\n try {\n owner = AV.User.current();\n } catch (error) {\n if ('SYNC_API_NOT_AVAILABLE' !== error.code) {\n throw error;\n }\n }\n }\n\n this.attributes.metaData.owner = owner ? owner.id : 'unknown';\n\n this.set('mime_type', mimeType);\n };\n\n /**\n * Creates a fresh AV.File object with exists url for saving to AVOS Cloud.\n * @param {String} name the file name\n * @param {String} url the file url.\n * @param {Object} [metaData] the file metadata object.\n * @param {String} [type] Content-Type header to use for the file. If\n * this is omitted, the content type will be inferred from the name's\n * extension.\n * @return {AV.File} the file object\n */\n AV.File.withURL = function(name, url, metaData, type) {\n if (!name || !url) {\n throw new Error('Please provide file name and url');\n }\n var file = new AV.File(name, null, type);\n //copy metaData properties to file.\n if (metaData) {\n for (var prop in metaData) {\n if (!file.attributes.metaData[prop])\n file.attributes.metaData[prop] = metaData[prop];\n }\n }\n file.attributes.url = url;\n //Mark the file is from external source.\n file.attributes.metaData.__source = 'external';\n file.attributes.metaData.size = 0;\n return file;\n };\n\n /**\n * Creates a file object with exists objectId.\n * @param {String} objectId The objectId string\n * @return {AV.File} the file object\n */\n AV.File.createWithoutData = function(objectId) {\n if (!objectId) {\n throw new TypeError('The objectId must be provided');\n }\n var file = new AV.File();\n file.id = objectId;\n return file;\n };\n\n /**\n * Request file censor.\n * @since 4.13.0\n * @param {String} objectId\n * @return {Promise.
Returns the file's metadata JSON object if no arguments is given.Returns the\n * metadata value if a key is given.Set metadata value if key and value are both given.
\n *\n * var metadata = file.metaData(); //Get metadata JSON object.\n * var size = file.metaData('size'); // Get the size metadata value.\n * file.metaData('format', 'jpeg'); //set metadata attribute and value.\n *\n * @return {Object} The file's metadata JSON object.\n * @param {String} attr an optional metadata key.\n * @param {Object} value an optional metadata value.\n **/\n metaData(attr, value) {\n if (attr && value) {\n this.attributes.metaData[attr] = value;\n return this;\n } else if (attr && !value) {\n return this.attributes.metaData[attr];\n } else {\n return this.attributes.metaData;\n }\n },\n\n /**\n * 如果文件是图片,获取图片的缩略图URL。可以传入宽度、高度、质量、格式等参数。\n * @return {String} 缩略图URL\n * @param {Number} width 宽度,单位:像素\n * @param {Number} heigth 高度,单位:像素\n * @param {Number} quality 质量,1-100的数字,默认100\n * @param {Number} scaleToFit 是否将图片自适应大小。默认为true。\n * @param {String} fmt 格式,默认为png,也可以为jpeg,gif等格式。\n */\n\n thumbnailURL(\n width,\n height,\n quality = 100,\n scaleToFit = true,\n fmt = 'png'\n ) {\n const url = this.attributes.url;\n if (!url) {\n throw new Error('Invalid url.');\n }\n if (!width || !height || width <= 0 || height <= 0) {\n throw new Error('Invalid width or height value.');\n }\n if (quality <= 0 || quality > 100) {\n throw new Error('Invalid quality value.');\n }\n const mode = scaleToFit ? 2 : 1;\n return (\n url +\n '?imageView/' +\n mode +\n '/w/' +\n width +\n '/h/' +\n height +\n '/q/' +\n quality +\n '/format/' +\n fmt\n );\n },\n\n /**\n * Returns the file's size.\n * @return {Number} The file's size in bytes.\n **/\n size() {\n return this.metaData().size;\n },\n\n /**\n * Returns the file's owner.\n * @return {String} The file's owner id.\n */\n ownerId() {\n return this.metaData().owner;\n },\n\n /**\n * Destroy the file.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the destroy\n * completes.\n */\n destroy(options) {\n if (!this.id) {\n return Promise.reject(new Error('The file id does not eixst.'));\n }\n var request = AVRequest(\n 'files',\n null,\n this.id,\n 'DELETE',\n null,\n options\n );\n return request;\n },\n\n /**\n * Request Qiniu upload token\n * @param {string} type\n * @return {Promise} Resolved with the response\n * @private\n */\n _fileToken(type, authOptions) {\n let name = this.attributes.name;\n\n let extName = extname(name);\n if (!extName && this._extName) {\n name += this._extName;\n extName = this._extName;\n }\n const data = {\n name,\n keep_file_name: authOptions.keepFileName,\n key: authOptions.key,\n ACL: this._acl,\n mime_type: type,\n metaData: this.attributes.metaData,\n };\n return AVRequest('fileTokens', null, null, 'POST', data, authOptions);\n },\n\n /**\n * @callback UploadProgressCallback\n * @param {XMLHttpRequestProgressEvent} event - The progress event with 'loaded' and 'total' attributes\n */\n /**\n * Saves the file to the AV cloud.\n * @param {AuthOptions} [options] AuthOptions plus:\n * @param {UploadProgressCallback} [options.onprogress] 文件上传进度,在 Node.js 中无效,回调参数说明详见 {@link UploadProgressCallback}。\n * @param {boolean} [options.keepFileName = false] 保留下载文件的文件名。\n * @param {string} [options.key] 指定文件的 key。设置该选项需要使用 masterKey\n * @return {Promise} Promise that is resolved when the save finishes.\n */\n save(options = {}) {\n if (this.id) {\n throw new Error('File is already saved.');\n }\n if (!this._previousSave) {\n if (this._data) {\n let mimeType = this.get('mime_type');\n this._previousSave = this._fileToken(mimeType, options).then(\n uploadInfo => {\n if (uploadInfo.mime_type) {\n mimeType = uploadInfo.mime_type;\n this.set('mime_type', mimeType);\n }\n this._token = uploadInfo.token;\n return Promise.resolve()\n .then(() => {\n const data = this._data;\n if (data && data.base64) {\n return parseBase64(data.base64, mimeType);\n }\n if (data && data.blob) {\n if (!data.blob.type && mimeType) {\n data.blob.type = mimeType;\n }\n if (!data.blob.name) {\n data.blob.name = this.get('name');\n }\n return data.blob;\n }\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n return data;\n }\n throw new TypeError('malformed file data');\n })\n .then(data => {\n const _options = _.extend({}, options);\n // filter out download progress events\n if (options.onprogress) {\n _options.onprogress = event => {\n if (event.direction === 'download') return;\n return options.onprogress(event);\n };\n }\n switch (uploadInfo.provider) {\n case 's3':\n return s3(uploadInfo, data, this, _options);\n case 'qcloud':\n return cos(uploadInfo, data, this, _options);\n case 'qiniu':\n default:\n return qiniu(uploadInfo, data, this, _options);\n }\n })\n .then(tap(() => this._callback(true)), error => {\n this._callback(false);\n throw error;\n });\n }\n );\n } else if (\n this.attributes.url &&\n this.attributes.metaData.__source === 'external'\n ) {\n // external link file.\n const data = {\n name: this.attributes.name,\n ACL: this._acl,\n metaData: this.attributes.metaData,\n mime_type: this.mimeType,\n url: this.attributes.url,\n };\n this._previousSave = AVRequest(\n 'files',\n null,\n null,\n 'post',\n data,\n options\n ).then(response => {\n this.id = response.objectId;\n return this;\n });\n }\n }\n return this._previousSave;\n },\n\n _callback(success) {\n AVRequest('fileCallback', null, null, 'post', {\n token: this._token,\n result: success,\n }).catch(debug);\n delete this._token;\n delete this._data;\n },\n\n /**\n * fetch the file from server. If the server's representation of the\n * model differs from its current attributes, they will be overriden,\n * @param {Object} fetchOptions Optional options to set 'keys',\n * 'include' and 'includeACL' option.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the fetch\n * completes.\n */\n fetch(fetchOptions, options) {\n if (!this.id) {\n throw new Error('Cannot fetch unsaved file');\n }\n var request = AVRequest(\n 'files',\n null,\n this.id,\n 'GET',\n transformFetchOptions(fetchOptions),\n options\n );\n return request.then(this._finishFetch.bind(this));\n },\n _finishFetch(response) {\n var value = AV.Object.prototype.parse(response);\n value.attributes = {\n name: value.name,\n url: value.url,\n mime_type: value.mime_type,\n bucket: value.bucket,\n };\n value.attributes.metaData = value.metaData || {};\n value.id = value.objectId;\n // clean\n delete value.objectId;\n delete value.metaData;\n delete value.url;\n delete value.name;\n delete value.mime_type;\n delete value.bucket;\n _.extend(this, value);\n return this;\n },\n\n /**\n * Request file censor\n * @since 4.13.0\n * @return {Promise.
You won't normally call this method directly. It is recommended that\n * you use a subclass of AV.Object
instead, created by calling\n * extend
.
However, if you don't want to use a subclass, or aren't sure which\n * subclass is appropriate, you can use this form:
\n * var object = new AV.Object(\"ClassName\");\n *\n * That is basically equivalent to:
\n * var MyClass = AV.Object.extend(\"ClassName\");\n * var object = new MyClass();\n *\n *\n * @param {Object} attributes The initial set of data to store in the object.\n * @param {Object} options A set of Backbone-like options for creating the\n * object. The only option currently supported is \"collection\".\n * @see AV.Object.extend\n *\n * @class\n *\n *
The fundamental unit of AV data, which implements the Backbone Model\n * interface.
\n */\n AV.Object = function(attributes, options) {\n // Allow new AV.Object(\"ClassName\") as a shortcut to _create.\n if (_.isString(attributes)) {\n return AV.Object._create.apply(this, arguments);\n }\n\n attributes = attributes || {};\n if (options && options.parse) {\n attributes = this.parse(attributes);\n attributes = this._mergeMagicFields(attributes);\n }\n var defaults = getValue(this, 'defaults');\n if (defaults) {\n attributes = _.extend({}, defaults, attributes);\n }\n if (options && options.collection) {\n this.collection = options.collection;\n }\n\n this._serverData = {}; // The last known data for this object from cloud.\n this._opSetQueue = [{}]; // List of sets of changes to the data.\n this._flags = {};\n this.attributes = {}; // The best estimate of this's current data.\n\n this._hashedJSON = {}; // Hash of values of containers at last save.\n this._escapedAttributes = {};\n this.cid = _.uniqueId('c');\n this.changed = {};\n this._silent = {};\n this._pending = {};\n this.set(attributes, { silent: true });\n this.changed = {};\n this._silent = {};\n this._pending = {};\n this._hasData = true;\n this._previousAttributes = _.clone(this.attributes);\n this.initialize.apply(this, arguments);\n };\n\n /**\n * @lends AV.Object.prototype\n * @property {String} id The objectId of the AV Object.\n */\n\n /**\n * Saves the given list of AV.Object.\n * If any error is encountered, stops and calls the error handler.\n *\n * @example\n * AV.Object.saveAll([object1, object2, ...]).then(function(list) {\n * // All the objects were saved.\n * }, function(error) {\n * // An error occurred while saving one of the objects.\n * });\n *\n * @param {Array} list A list ofAV.Object
.\n */\n AV.Object.saveAll = function(list, options) {\n return AV.Object._deepSaveAsync(list, null, options);\n };\n\n /**\n * Fetch the given list of AV.Object.\n *\n * @param {AV.Object[]} objects A list of AV.Object
\n * @param {AuthOptions} options\n * @return {Promise.AV.Object
, updated\n */\n\n AV.Object.fetchAll = (objects, options) =>\n Promise.resolve()\n .then(() =>\n _request(\n 'batch',\n null,\n null,\n 'POST',\n {\n requests: _.map(objects, object => {\n if (!object.className)\n throw new Error('object must have className to fetch');\n if (!object.id) throw new Error('object must have id to fetch');\n if (object.dirty())\n throw new Error('object is modified but not saved');\n return {\n method: 'GET',\n path: `/1.1/classes/${object.className}/${object.id}`,\n };\n }),\n },\n options\n )\n )\n .then(function(response) {\n const results = _.map(objects, function(object, i) {\n if (response[i].success) {\n const fetchedAttrs = object.parse(response[i].success);\n object._cleanupUnsetKeys(fetchedAttrs);\n object._finishFetch(fetchedAttrs);\n return object;\n }\n if (response[i].success === null) {\n return new AVError(AVError.OBJECT_NOT_FOUND, 'Object not found.');\n }\n return new AVError(response[i].error.code, response[i].error.error);\n });\n return handleBatchResults(results);\n });\n\n // Attach all inheritable methods to the AV.Object prototype.\n _.extend(\n AV.Object.prototype,\n AV.Events,\n /** @lends AV.Object.prototype */ {\n _fetchWhenSave: false,\n\n /**\n * Initialize is an empty function by default. Override it with your own\n * initialization logic.\n */\n initialize: function() {},\n\n /**\n * Set whether to enable fetchWhenSave option when updating object.\n * When set true, SDK would fetch the latest object after saving.\n * Default is false.\n *\n * @deprecated use AV.Object#save with options.fetchWhenSave instead\n * @param {boolean} enable true to enable fetchWhenSave option.\n */\n fetchWhenSave: function(enable) {\n console.warn(\n 'AV.Object#fetchWhenSave is deprecated, use AV.Object#save with options.fetchWhenSave instead.'\n );\n if (!_.isBoolean(enable)) {\n throw new Error('Expect boolean value for fetchWhenSave');\n }\n this._fetchWhenSave = enable;\n },\n\n /**\n * Returns the object's objectId.\n * @return {String} the objectId.\n */\n getObjectId: function() {\n return this.id;\n },\n\n /**\n * Returns the object's createdAt attribute.\n * @return {Date}\n */\n getCreatedAt: function() {\n return this.createdAt;\n },\n\n /**\n * Returns the object's updatedAt attribute.\n * @return {Date}\n */\n getUpdatedAt: function() {\n return this.updatedAt;\n },\n\n /**\n * Returns a JSON version of the object.\n * @return {Object}\n */\n toJSON: function(key, holder, seenObjects = []) {\n return this._toFullJSON(seenObjects, false);\n },\n\n /**\n * Returns a JSON version of the object with meta data.\n * Inverse to {@link AV.parseJSON}\n * @since 3.0.0\n * @return {Object}\n */\n toFullJSON(seenObjects = []) {\n return this._toFullJSON(seenObjects);\n },\n\n _toFullJSON: function(seenObjects, full = true) {\n var json = _.clone(this.attributes);\n if (_.isArray(seenObjects)) {\n var newSeenObjects = seenObjects.concat(this);\n }\n AV._objectEach(json, function(val, key) {\n json[key] = AV._encode(val, newSeenObjects, undefined, full);\n });\n AV._objectEach(this._operations, function(val, key) {\n json[key] = val;\n });\n\n if (_.has(this, 'id')) {\n json.objectId = this.id;\n }\n ['createdAt', 'updatedAt'].forEach(key => {\n if (_.has(this, key)) {\n const val = this[key];\n json[key] = _.isDate(val) ? val.toJSON() : val;\n }\n });\n if (full) {\n json.__type = 'Object';\n if (_.isArray(seenObjects) && seenObjects.length)\n json.__type = 'Pointer';\n json.className = this.className;\n }\n return json;\n },\n\n /**\n * Updates _hashedJSON to reflect the current state of this object.\n * Adds any changed hash values to the set of pending changes.\n * @private\n */\n _refreshCache: function() {\n var self = this;\n if (self._refreshingCache) {\n return;\n }\n self._refreshingCache = true;\n AV._objectEach(this.attributes, function(value, key) {\n if (value instanceof AV.Object) {\n value._refreshCache();\n } else if (_.isObject(value)) {\n if (self._resetCacheForKey(key)) {\n self.set(key, new AV.Op.Set(value), { silent: true });\n }\n }\n });\n delete self._refreshingCache;\n },\n\n /**\n * Returns true if this object has been modified since its last\n * save/refresh. If an attribute is specified, it returns true only if that\n * particular attribute has been modified since the last save/refresh.\n * @param {String} attr An attribute name (optional).\n * @return {Boolean}\n */\n dirty: function(attr) {\n this._refreshCache();\n\n var currentChanges = _.last(this._opSetQueue);\n\n if (attr) {\n return currentChanges[attr] ? true : false;\n }\n if (!this.id) {\n return true;\n }\n if (_.keys(currentChanges).length > 0) {\n return true;\n }\n return false;\n },\n\n /**\n * Returns the keys of the modified attribute since its last save/refresh.\n * @return {String[]}\n */\n dirtyKeys: function() {\n this._refreshCache();\n var currentChanges = _.last(this._opSetQueue);\n return _.keys(currentChanges);\n },\n\n /**\n * Gets a Pointer referencing this Object.\n * @private\n */\n _toPointer: function() {\n // if (!this.id) {\n // throw new Error(\"Can't serialize an unsaved AV.Object\");\n // }\n return {\n __type: 'Pointer',\n className: this.className,\n objectId: this.id,\n };\n },\n\n /**\n * Gets the value of an attribute.\n * @param {String} attr The string name of an attribute.\n */\n get: function(attr) {\n switch (attr) {\n case 'objectId':\n return this.id;\n case 'createdAt':\n case 'updatedAt':\n return this[attr];\n default:\n return this.attributes[attr];\n }\n },\n\n /**\n * Gets a relation on the given class for the attribute.\n * @param {String} attr The attribute to get the relation for.\n * @return {AV.Relation}\n */\n relation: function(attr) {\n var value = this.get(attr);\n if (value) {\n if (!(value instanceof AV.Relation)) {\n throw new Error('Called relation() on non-relation field ' + attr);\n }\n value._ensureParentAndKey(this, attr);\n return value;\n } else {\n return new AV.Relation(this, attr);\n }\n },\n\n /**\n * Gets the HTML-escaped value of an attribute.\n */\n escape: function(attr) {\n var html = this._escapedAttributes[attr];\n if (html) {\n return html;\n }\n var val = this.attributes[attr];\n var escaped;\n if (isNullOrUndefined(val)) {\n escaped = '';\n } else {\n escaped = _.escape(val.toString());\n }\n this._escapedAttributes[attr] = escaped;\n return escaped;\n },\n\n /**\n * Returns true
if the attribute contains a value that is not\n * null or undefined.\n * @param {String} attr The string name of the attribute.\n * @return {Boolean}\n */\n has: function(attr) {\n return !isNullOrUndefined(this.attributes[attr]);\n },\n\n /**\n * Pulls \"special\" fields like objectId, createdAt, etc. out of attrs\n * and puts them on \"this\" directly. Removes them from attrs.\n * @param attrs - A dictionary with the data for this AV.Object.\n * @private\n */\n _mergeMagicFields: function(attrs) {\n // Check for changes of magic fields.\n var model = this;\n var specialFields = ['objectId', 'createdAt', 'updatedAt'];\n AV._arrayEach(specialFields, function(attr) {\n if (attrs[attr]) {\n if (attr === 'objectId') {\n model.id = attrs[attr];\n } else if (\n (attr === 'createdAt' || attr === 'updatedAt') &&\n !_.isDate(attrs[attr])\n ) {\n model[attr] = AV._parseDate(attrs[attr]);\n } else {\n model[attr] = attrs[attr];\n }\n delete attrs[attr];\n }\n });\n return attrs;\n },\n\n /**\n * Returns the json to be sent to the server.\n * @private\n */\n _startSave: function() {\n this._opSetQueue.push({});\n },\n\n /**\n * Called when a save fails because of an error. Any changes that were part\n * of the save need to be merged with changes made after the save. This\n * might throw an exception is you do conflicting operations. For example,\n * if you do:\n * object.set(\"foo\", \"bar\");\n * object.set(\"invalid field name\", \"baz\");\n * object.save();\n * object.increment(\"foo\");\n * then this will throw when the save fails and the client tries to merge\n * \"bar\" with the +1.\n * @private\n */\n _cancelSave: function() {\n var failedChanges = _.first(this._opSetQueue);\n this._opSetQueue = _.rest(this._opSetQueue);\n var nextChanges = _.first(this._opSetQueue);\n AV._objectEach(failedChanges, function(op, key) {\n var op1 = failedChanges[key];\n var op2 = nextChanges[key];\n if (op1 && op2) {\n nextChanges[key] = op2._mergeWithPrevious(op1);\n } else if (op1) {\n nextChanges[key] = op1;\n }\n });\n this._saving = this._saving - 1;\n },\n\n /**\n * Called when a save completes successfully. This merges the changes that\n * were saved into the known server data, and overrides it with any data\n * sent directly from the server.\n * @private\n */\n _finishSave: function(serverData) {\n // Grab a copy of any object referenced by this object. These instances\n // may have already been fetched, and we don't want to lose their data.\n // Note that doing it like this means we will unify separate copies of the\n // same object, but that's a risk we have to take.\n var fetchedObjects = {};\n AV._traverse(this.attributes, function(object) {\n if (object instanceof AV.Object && object.id && object._hasData) {\n fetchedObjects[object.id] = object;\n }\n });\n\n var savedChanges = _.first(this._opSetQueue);\n this._opSetQueue = _.rest(this._opSetQueue);\n this._applyOpSet(savedChanges, this._serverData);\n this._mergeMagicFields(serverData);\n var self = this;\n AV._objectEach(serverData, function(value, key) {\n self._serverData[key] = AV._decode(value, key);\n\n // Look for any objects that might have become unfetched and fix them\n // by replacing their values with the previously observed values.\n var fetched = AV._traverse(self._serverData[key], function(object) {\n if (object instanceof AV.Object && fetchedObjects[object.id]) {\n return fetchedObjects[object.id];\n }\n });\n if (fetched) {\n self._serverData[key] = fetched;\n }\n });\n this._rebuildAllEstimatedData();\n const opSetQueue = this._opSetQueue.map(_.clone);\n this._refreshCache();\n this._opSetQueue = opSetQueue;\n this._saving = this._saving - 1;\n },\n\n /**\n * Called when a fetch or login is complete to set the known server data to\n * the given object.\n * @private\n */\n _finishFetch: function(serverData, hasData) {\n // Clear out any changes the user might have made previously.\n this._opSetQueue = [{}];\n\n // Bring in all the new server data.\n this._mergeMagicFields(serverData);\n var self = this;\n AV._objectEach(serverData, function(value, key) {\n self._serverData[key] = AV._decode(value, key);\n });\n\n // Refresh the attributes.\n this._rebuildAllEstimatedData();\n\n // Clear out the cache of mutable containers.\n this._refreshCache();\n this._opSetQueue = [{}];\n\n this._hasData = hasData;\n },\n\n /**\n * Applies the set of AV.Op in opSet to the object target.\n * @private\n */\n _applyOpSet: function(opSet, target) {\n var self = this;\n AV._objectEach(opSet, function(change, key) {\n const [value, actualTarget, actualKey] = findValue(target, key);\n setValue(target, key, change._estimate(value, self, key));\n if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {\n delete actualTarget[actualKey];\n }\n });\n },\n\n /**\n * Replaces the cached value for key with the current value.\n * Returns true if the new value is different than the old value.\n * @private\n */\n _resetCacheForKey: function(key) {\n var value = this.attributes[key];\n if (\n _.isObject(value) &&\n !(value instanceof AV.Object) &&\n !(value instanceof AV.File)\n ) {\n var json = JSON.stringify(recursiveToPointer(value));\n if (this._hashedJSON[key] !== json) {\n var wasSet = !!this._hashedJSON[key];\n this._hashedJSON[key] = json;\n return wasSet;\n }\n }\n return false;\n },\n\n /**\n * Populates attributes[key] by starting with the last known data from the\n * server, and applying all of the local changes that have been made to that\n * key since then.\n * @private\n */\n _rebuildEstimatedDataForKey: function(key) {\n var self = this;\n delete this.attributes[key];\n if (this._serverData[key]) {\n this.attributes[key] = this._serverData[key];\n }\n AV._arrayEach(this._opSetQueue, function(opSet) {\n var op = opSet[key];\n if (op) {\n const [value, actualTarget, actualKey, firstKey] = findValue(\n self.attributes,\n key\n );\n setValue(self.attributes, key, op._estimate(value, self, key));\n if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {\n delete actualTarget[actualKey];\n }\n self._resetCacheForKey(firstKey);\n }\n });\n },\n\n /**\n * Populates attributes by starting with the last known data from the\n * server, and applying all of the local changes that have been made since\n * then.\n * @private\n */\n _rebuildAllEstimatedData: function() {\n var self = this;\n\n var previousAttributes = _.clone(this.attributes);\n\n this.attributes = _.clone(this._serverData);\n AV._arrayEach(this._opSetQueue, function(opSet) {\n self._applyOpSet(opSet, self.attributes);\n AV._objectEach(opSet, function(op, key) {\n self._resetCacheForKey(key);\n });\n });\n\n // Trigger change events for anything that changed because of the fetch.\n AV._objectEach(previousAttributes, function(oldValue, key) {\n if (self.attributes[key] !== oldValue) {\n self.trigger('change:' + key, self, self.attributes[key], {});\n }\n });\n AV._objectEach(this.attributes, function(newValue, key) {\n if (!_.has(previousAttributes, key)) {\n self.trigger('change:' + key, self, newValue, {});\n }\n });\n },\n\n /**\n * Sets a hash of model attributes on the object, firing\n * \"change\"
unless you choose to silence it.\n *\n * You can call it with an object containing keys and values, or with one\n * key and value. For example:
\n *\n * @example\n * gameTurn.set({\n * player: player1,\n * diceRoll: 2\n * });\n *\n * game.set(\"currentPlayer\", player2);\n *\n * game.set(\"finished\", true);\n *\n * @param {String} key The key to set.\n * @param {Any} value The value to give it.\n * @param {Object} [options]\n * @param {Boolean} [options.silent]\n * @return {AV.Object} self if succeeded, throws if the value is not valid.\n * @see AV.Object#validate\n */\n set: function(key, value, options) {\n var attrs;\n if (_.isObject(key) || isNullOrUndefined(key)) {\n attrs = _.mapObject(key, function(v, k) {\n checkReservedKey(k);\n return AV._decode(v, k);\n });\n options = value;\n } else {\n attrs = {};\n checkReservedKey(key);\n attrs[key] = AV._decode(value, key);\n }\n\n // Extract attributes and options.\n options = options || {};\n if (!attrs) {\n return this;\n }\n if (attrs instanceof AV.Object) {\n attrs = attrs.attributes;\n }\n\n // If the unset option is used, every attribute should be a Unset.\n if (options.unset) {\n AV._objectEach(attrs, function(unused_value, key) {\n attrs[key] = new AV.Op.Unset();\n });\n }\n\n // Apply all the attributes to get the estimated values.\n var dataToValidate = _.clone(attrs);\n var self = this;\n AV._objectEach(dataToValidate, function(value, key) {\n if (value instanceof AV.Op) {\n dataToValidate[key] = value._estimate(\n self.attributes[key],\n self,\n key\n );\n if (dataToValidate[key] === AV.Op._UNSET) {\n delete dataToValidate[key];\n }\n }\n });\n\n // Run validation.\n this._validate(attrs, options);\n\n options.changes = {};\n var escaped = this._escapedAttributes;\n\n // Update attributes.\n AV._arrayEach(_.keys(attrs), function(attr) {\n var val = attrs[attr];\n\n // If this is a relation object we need to set the parent correctly,\n // since the location where it was parsed does not have access to\n // this object.\n if (val instanceof AV.Relation) {\n val.parent = self;\n }\n\n if (!(val instanceof AV.Op)) {\n val = new AV.Op.Set(val);\n }\n\n // See if this change will actually have any effect.\n var isRealChange = true;\n if (\n val instanceof AV.Op.Set &&\n _.isEqual(self.attributes[attr], val.value)\n ) {\n isRealChange = false;\n }\n\n if (isRealChange) {\n delete escaped[attr];\n if (options.silent) {\n self._silent[attr] = true;\n } else {\n options.changes[attr] = true;\n }\n }\n\n var currentChanges = _.last(self._opSetQueue);\n currentChanges[attr] = val._mergeWithPrevious(currentChanges[attr]);\n self._rebuildEstimatedDataForKey(attr);\n\n if (isRealChange) {\n self.changed[attr] = self.attributes[attr];\n if (!options.silent) {\n self._pending[attr] = true;\n }\n } else {\n delete self.changed[attr];\n delete self._pending[attr];\n }\n });\n\n if (!options.silent) {\n this.change(options);\n }\n return this;\n },\n\n /**\n * Remove an attribute from the model, firing\"change\"
unless\n * you choose to silence it. This is a noop if the attribute doesn't\n * exist.\n * @param key {String} The key.\n */\n unset: function(attr, options) {\n options = options || {};\n options.unset = true;\n return this.set(attr, null, options);\n },\n\n /**\n * Atomically increments the value of the given attribute the next time the\n * object is saved. If no amount is specified, 1 is used by default.\n *\n * @param key {String} The key.\n * @param amount {Number} The amount to increment by.\n */\n increment: function(attr, amount) {\n if (_.isUndefined(amount) || _.isNull(amount)) {\n amount = 1;\n }\n return this.set(attr, new AV.Op.Increment(amount));\n },\n\n /**\n * Atomically add an object to the end of the array associated with a given\n * key.\n * @param key {String} The key.\n * @param item {} The item to add.\n */\n add: function(attr, item) {\n return this.set(attr, new AV.Op.Add(ensureArray(item)));\n },\n\n /**\n * Atomically add an object to the array associated with a given key, only\n * if it is not already present in the array. The position of the insert is\n * not guaranteed.\n *\n * @param key {String} The key.\n * @param item {} The object to add.\n */\n addUnique: function(attr, item) {\n return this.set(attr, new AV.Op.AddUnique(ensureArray(item)));\n },\n\n /**\n * Atomically remove all instances of an object from the array associated\n * with a given key.\n *\n * @param key {String} The key.\n * @param item {} The object to remove.\n */\n remove: function(attr, item) {\n return this.set(attr, new AV.Op.Remove(ensureArray(item)));\n },\n\n /**\n * Atomically apply a \"bit and\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitAnd(attr, value) {\n return this.set(attr, new AV.Op.BitAnd(value));\n },\n\n /**\n * Atomically apply a \"bit or\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitOr(attr, value) {\n return this.set(attr, new AV.Op.BitOr(value));\n },\n\n /**\n * Atomically apply a \"bit xor\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitXor(attr, value) {\n return this.set(attr, new AV.Op.BitXor(value));\n },\n\n /**\n * Returns an instance of a subclass of AV.Op describing what kind of\n * modification has been performed on this field since the last time it was\n * saved. For example, after calling object.increment(\"x\"), calling\n * object.op(\"x\") would return an instance of AV.Op.Increment.\n *\n * @param key {String} The key.\n * @returns {AV.Op} The operation, or undefined if none.\n */\n op: function(attr) {\n return _.last(this._opSetQueue)[attr];\n },\n\n /**\n * Clear all attributes on the model, firing \"change\"
unless\n * you choose to silence it.\n */\n clear: function(options) {\n options = options || {};\n options.unset = true;\n var keysToClear = _.extend(this.attributes, this._operations);\n return this.set(keysToClear, options);\n },\n\n /**\n * Clears any (or specific) changes to the model made since the last save.\n * @param {string|string[]} [keys] specify keys to revert.\n */\n revert(keys) {\n const lastOp = _.last(this._opSetQueue);\n const _keys = ensureArray(keys || _.keys(lastOp));\n _keys.forEach(key => {\n delete lastOp[key];\n });\n this._rebuildAllEstimatedData();\n return this;\n },\n\n /**\n * Returns a JSON-encoded set of operations to be sent with the next save\n * request.\n * @private\n */\n _getSaveJSON: function() {\n var json = _.clone(_.first(this._opSetQueue));\n AV._objectEach(json, function(op, key) {\n json[key] = op.toJSON();\n });\n return json;\n },\n\n /**\n * Returns true if this object can be serialized for saving.\n * @private\n */\n _canBeSerialized: function() {\n return AV.Object._canBeSerializedAsValue(this.attributes);\n },\n\n /**\n * Fetch the model from the server. If the server's representation of the\n * model differs from its current attributes, they will be overriden,\n * triggering a \"change\"
event.\n * @param {Object} fetchOptions Optional options to set 'keys',\n * 'include' and 'includeACL' option.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the fetch\n * completes.\n */\n fetch: function(fetchOptions = {}, options) {\n if (!this.id) {\n throw new Error('Cannot fetch unsaved object');\n }\n var self = this;\n var request = _request(\n 'classes',\n this.className,\n this.id,\n 'GET',\n transformFetchOptions(fetchOptions),\n options\n );\n return request.then(function(response) {\n const fetchedAttrs = self.parse(response);\n self._cleanupUnsetKeys(\n fetchedAttrs,\n fetchOptions.keys\n ? ensureArray(fetchOptions.keys)\n .join(',')\n .split(',')\n : undefined\n );\n self._finishFetch(fetchedAttrs, true);\n return self;\n });\n },\n\n _cleanupUnsetKeys(fetchedAttrs, fetchedKeys = _.keys(this._serverData)) {\n _.forEach(fetchedKeys, key => {\n if (fetchedAttrs[key] === undefined) delete this._serverData[key];\n });\n },\n\n /**\n * Set a hash of model attributes, and save the model to the server.\n * updatedAt will be updated when the request returns.\n * You can either call it as:\n * object.save();\n * or
\n * object.save(null, options);\n * or
\n * object.save(attrs, options);\n * or
\n * object.save(key, value, options);\n *\n * @example\n * gameTurn.save({\n * player: \"Jake Cutter\",\n * diceRoll: 2\n * }).then(function(gameTurnAgain) {\n * // The save was successful.\n * }, function(error) {\n * // The save failed. Error is an instance of AVError.\n * });\n *\n * @param {AuthOptions} options AuthOptions plus:\n * @param {Boolean} options.fetchWhenSave fetch and update object after save succeeded\n * @param {AV.Query} options.query Save object only when it matches the query\n * @return {Promise} A promise that is fulfilled when the save\n * completes.\n * @see AVError\n */\n save: function(arg1, arg2, arg3) {\n var attrs, current, options;\n if (_.isObject(arg1) || isNullOrUndefined(arg1)) {\n attrs = arg1;\n options = arg2;\n } else {\n attrs = {};\n attrs[arg1] = arg2;\n options = arg3;\n }\n\n options = _.clone(options) || {};\n if (options.wait) {\n current = _.clone(this.attributes);\n }\n\n var setOptions = _.clone(options) || {};\n if (setOptions.wait) {\n setOptions.silent = true;\n }\n if (attrs) {\n this.set(attrs, setOptions);\n }\n\n var model = this;\n\n var unsavedChildren = [];\n var unsavedFiles = [];\n AV.Object._findUnsavedChildren(model, unsavedChildren, unsavedFiles);\n if (unsavedChildren.length + unsavedFiles.length > 1) {\n return AV.Object._deepSaveAsync(this, model, options);\n }\n\n this._startSave();\n this._saving = (this._saving || 0) + 1;\n\n this._allPreviousSaves = this._allPreviousSaves || Promise.resolve();\n this._allPreviousSaves = this._allPreviousSaves\n .catch(e => {})\n .then(function() {\n var method = model.id ? 'PUT' : 'POST';\n\n var json = model._getSaveJSON();\n var query = {};\n\n if (model._fetchWhenSave || options.fetchWhenSave) {\n query['new'] = 'true';\n }\n // user login option\n if (options._failOnNotExist) {\n query.failOnNotExist = 'true';\n }\n\n if (options.query) {\n var queryParams;\n if (typeof options.query._getParams === 'function') {\n queryParams = options.query._getParams();\n if (queryParams) {\n query.where = queryParams.where;\n }\n }\n if (!query.where) {\n var error = new Error('options.query is not an AV.Query');\n throw error;\n }\n }\n\n _.extend(json, model._flags);\n\n var route = 'classes';\n var className = model.className;\n if (model.className === '_User' && !model.id) {\n // Special-case user sign-up.\n route = 'users';\n className = null;\n }\n //hook makeRequest in options.\n var makeRequest = options._makeRequest || _request;\n var requestPromise = makeRequest(\n route,\n className,\n model.id,\n method,\n json,\n options,\n query\n );\n\n requestPromise = requestPromise.then(\n function(resp) {\n var serverAttrs = model.parse(resp);\n if (options.wait) {\n serverAttrs = _.extend(attrs || {}, serverAttrs);\n }\n model._finishSave(serverAttrs);\n if (options.wait) {\n model.set(current, setOptions);\n }\n return model;\n },\n function(error) {\n model._cancelSave();\n throw error;\n }\n );\n\n return requestPromise;\n });\n return this._allPreviousSaves;\n },\n\n /**\n * Destroy this model on the server if it was already persisted.\n * Optimistically removes the model from its collection, if it has one.\n * @param {AuthOptions} options AuthOptions plus:\n * @param {Boolean} [options.wait] wait for the server to respond\n * before removal.\n *\n * @return {Promise} A promise that is fulfilled when the destroy\n * completes.\n */\n destroy: function(options) {\n options = options || {};\n var model = this;\n\n var triggerDestroy = function() {\n model.trigger('destroy', model, model.collection, options);\n };\n\n if (!this.id) {\n return triggerDestroy();\n }\n\n if (!options.wait) {\n triggerDestroy();\n }\n\n var request = _request(\n 'classes',\n this.className,\n this.id,\n 'DELETE',\n this._flags,\n options\n );\n return request.then(function() {\n if (options.wait) {\n triggerDestroy();\n }\n return model;\n });\n },\n\n /**\n * Converts a response into the hash of attributes to be set on the model.\n * @ignore\n */\n parse: function(resp) {\n var output = _.clone(resp);\n ['createdAt', 'updatedAt'].forEach(function(key) {\n if (output[key]) {\n output[key] = AV._parseDate(output[key]);\n }\n });\n if (output.createdAt && !output.updatedAt) {\n output.updatedAt = output.createdAt;\n }\n return output;\n },\n\n /**\n * Creates a new model with identical attributes to this one.\n * @return {AV.Object}\n */\n clone: function() {\n return new this.constructor(this.attributes);\n },\n\n /**\n * Returns true if this object has never been saved to AV.\n * @return {Boolean}\n */\n isNew: function() {\n return !this.id;\n },\n\n /**\n * Call this method to manually fire a `\"change\"` event for this model and\n * a `\"change:attribute\"` event for each changed attribute.\n * Calling this will cause all objects observing the model to update.\n */\n change: function(options) {\n options = options || {};\n var changing = this._changing;\n this._changing = true;\n\n // Silent changes become pending changes.\n var self = this;\n AV._objectEach(this._silent, function(attr) {\n self._pending[attr] = true;\n });\n\n // Silent changes are triggered.\n var changes = _.extend({}, options.changes, this._silent);\n this._silent = {};\n AV._objectEach(changes, function(unused_value, attr) {\n self.trigger('change:' + attr, self, self.get(attr), options);\n });\n if (changing) {\n return this;\n }\n\n // This is to get around lint not letting us make a function in a loop.\n var deleteChanged = function(value, attr) {\n if (!self._pending[attr] && !self._silent[attr]) {\n delete self.changed[attr];\n }\n };\n\n // Continue firing `\"change\"` events while there are pending changes.\n while (!_.isEmpty(this._pending)) {\n this._pending = {};\n this.trigger('change', this, options);\n // Pending and silent changes still remain.\n AV._objectEach(this.changed, deleteChanged);\n self._previousAttributes = _.clone(this.attributes);\n }\n\n this._changing = false;\n return this;\n },\n\n /**\n * Gets the previous value of an attribute, recorded at the time the last\n *
\"change\"
event was fired.\n * @param {String} attr Name of the attribute to get.\n */\n previous: function(attr) {\n if (!arguments.length || !this._previousAttributes) {\n return null;\n }\n return this._previousAttributes[attr];\n },\n\n /**\n * Gets all of the attributes of the model at the time of the previous\n * \"change\"
event.\n * @return {Object}\n */\n previousAttributes: function() {\n return _.clone(this._previousAttributes);\n },\n\n /**\n * Checks if the model is currently in a valid state. It's only possible to\n * get into an *invalid* state if you're using silent changes.\n * @return {Boolean}\n */\n isValid: function() {\n try {\n this.validate(this.attributes);\n } catch (error) {\n return false;\n }\n return true;\n },\n\n /**\n * You should not call this function directly unless you subclass\n * AV.Object
, in which case you can override this method\n * to provide additional validation on set
and\n * save
. Your implementation should throw an Error if\n * the attrs is invalid\n *\n * @param {Object} attrs The current data to validate.\n * @see AV.Object#set\n */\n validate: function(attrs) {\n if (_.has(attrs, 'ACL') && !(attrs.ACL instanceof AV.ACL)) {\n throw new AVError(AVError.OTHER_CAUSE, 'ACL must be a AV.ACL.');\n }\n },\n\n /**\n * Run validation against a set of incoming attributes, returning `true`\n * if all is well. If a specific `error` callback has been passed,\n * call that instead of firing the general `\"error\"` event.\n * @private\n */\n _validate: function(attrs, options) {\n if (options.silent || !this.validate) {\n return;\n }\n attrs = _.extend({}, this.attributes, attrs);\n this.validate(attrs);\n },\n\n /**\n * Returns the ACL for this object.\n * @returns {AV.ACL} An instance of AV.ACL.\n * @see AV.Object#get\n */\n getACL: function() {\n return this.get('ACL');\n },\n\n /**\n * Sets the ACL to be used for this object.\n * @param {AV.ACL} acl An instance of AV.ACL.\n * @param {Object} options Optional Backbone-like options object to be\n * passed in to set.\n * @return {AV.Object} self\n * @see AV.Object#set\n */\n setACL: function(acl, options) {\n return this.set('ACL', acl, options);\n },\n\n disableBeforeHook: function() {\n this.ignoreHook('beforeSave');\n this.ignoreHook('beforeUpdate');\n this.ignoreHook('beforeDelete');\n },\n\n disableAfterHook: function() {\n this.ignoreHook('afterSave');\n this.ignoreHook('afterUpdate');\n this.ignoreHook('afterDelete');\n },\n\n ignoreHook: function(hookName) {\n if (\n !_.contains(\n [\n 'beforeSave',\n 'afterSave',\n 'beforeUpdate',\n 'afterUpdate',\n 'beforeDelete',\n 'afterDelete',\n ],\n hookName\n )\n ) {\n throw new Error('Unsupported hookName: ' + hookName);\n }\n\n if (!AV.hookKey) {\n throw new Error('ignoreHook required hookKey');\n }\n\n if (!this._flags.__ignore_hooks) {\n this._flags.__ignore_hooks = [];\n }\n\n this._flags.__ignore_hooks.push(hookName);\n },\n }\n );\n\n /**\n * Creates an instance of a subclass of AV.Object for the give classname\n * and id.\n * @param {String|Function} class the className or a subclass of AV.Object.\n * @param {String} id The object id of this model.\n * @return {AV.Object} A new subclass instance of AV.Object.\n */\n AV.Object.createWithoutData = (klass, id, hasData) => {\n let _klass;\n if (_.isString(klass)) {\n _klass = AV.Object._getSubclass(klass);\n } else if (klass.prototype && klass.prototype instanceof AV.Object) {\n _klass = klass;\n } else {\n throw new Error('class must be a string or a subclass of AV.Object.');\n }\n if (!id) {\n throw new TypeError('The objectId must be provided');\n }\n const object = new _klass();\n object.id = id;\n object._hasData = hasData;\n return object;\n };\n /**\n * Delete objects in batch.\n * @param {AV.Object[]} objects The AV.Object
array to be deleted.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the save\n * completes.\n */\n AV.Object.destroyAll = function(objects, options = {}) {\n if (!objects || objects.length === 0) {\n return Promise.resolve();\n }\n const objectsByClassNameAndFlags = _.groupBy(objects, object =>\n JSON.stringify({\n className: object.className,\n flags: object._flags,\n })\n );\n const body = {\n requests: _.map(objectsByClassNameAndFlags, objects => {\n const ids = _.map(objects, 'id').join(',');\n return {\n method: 'DELETE',\n path: `/1.1/classes/${objects[0].className}/${ids}`,\n body: objects[0]._flags,\n };\n }),\n };\n return _request('batch', null, null, 'POST', body, options).then(\n response => {\n const firstError = _.find(response, result => !result.success);\n if (firstError)\n throw new AVError(firstError.error.code, firstError.error.error);\n return undefined;\n }\n );\n };\n\n /**\n * Returns the appropriate subclass for making new instances of the given\n * className string.\n * @private\n */\n AV.Object._getSubclass = function(className) {\n if (!_.isString(className)) {\n throw new Error('AV.Object._getSubclass requires a string argument.');\n }\n var ObjectClass = AV.Object._classMap[className];\n if (!ObjectClass) {\n ObjectClass = AV.Object.extend(className);\n AV.Object._classMap[className] = ObjectClass;\n }\n return ObjectClass;\n };\n\n /**\n * Creates an instance of a subclass of AV.Object for the given classname.\n * @private\n */\n AV.Object._create = function(className, attributes, options) {\n var ObjectClass = AV.Object._getSubclass(className);\n return new ObjectClass(attributes, options);\n };\n\n // Set up a map of className to class so that we can create new instances of\n // AV Objects from JSON automatically.\n AV.Object._classMap = {};\n\n AV.Object._extend = AV._extend;\n\n /**\n * Creates a new model with defined attributes,\n * It's the same with\n * \n * new AV.Object(attributes, options);\n *\n * @param {Object} attributes The initial set of data to store in the object.\n * @param {Object} options A set of Backbone-like options for creating the\n * object. The only option currently supported is \"collection\".\n * @return {AV.Object}\n * @since v0.4.4\n * @see AV.Object\n * @see AV.Object.extend\n */\n AV.Object['new'] = function(attributes, options) {\n return new AV.Object(attributes, options);\n };\n\n /**\n * Creates a new subclass of AV.Object for the given AV class name.\n *\n *
Every extension of a AV class will inherit from the most recent\n * previous extension of that class. When a AV.Object is automatically\n * created by parsing JSON, it will use the most recent extension of that\n * class.
\n *\n * @example\n * var MyClass = AV.Object.extend(\"MyClass\", {\n * // Instance properties\n * }, {\n * // Class properties\n * });\n *\n * @param {String} className The name of the AV class backing this model.\n * @param {Object} protoProps Instance properties to add to instances of the\n * class returned from this method.\n * @param {Object} classProps Class properties to add the class returned from\n * this method.\n * @return {Class} A new subclass of AV.Object.\n */\n AV.Object.extend = function(className, protoProps, classProps) {\n // Handle the case with only two args.\n if (!_.isString(className)) {\n if (className && _.has(className, 'className')) {\n return AV.Object.extend(className.className, className, protoProps);\n } else {\n throw new Error(\n \"AV.Object.extend's first argument should be the className.\"\n );\n }\n }\n\n // If someone tries to subclass \"User\", coerce it to the right type.\n if (className === 'User') {\n className = '_User';\n }\n\n var NewClassObject = null;\n if (_.has(AV.Object._classMap, className)) {\n var OldClassObject = AV.Object._classMap[className];\n // This new subclass has been told to extend both from \"this\" and from\n // OldClassObject. This is multiple inheritance, which isn't supported.\n // For now, let's just pick one.\n if (protoProps || classProps) {\n NewClassObject = OldClassObject._extend(protoProps, classProps);\n } else {\n return OldClassObject;\n }\n } else {\n protoProps = protoProps || {};\n protoProps._className = className;\n NewClassObject = this._extend(protoProps, classProps);\n }\n // Extending a subclass should reuse the classname automatically.\n NewClassObject.extend = function(arg0) {\n if (_.isString(arg0) || (arg0 && _.has(arg0, 'className'))) {\n return AV.Object.extend.apply(NewClassObject, arguments);\n }\n var newArguments = [className].concat(_.toArray(arguments));\n return AV.Object.extend.apply(NewClassObject, newArguments);\n };\n // Add the query property descriptor.\n Object.defineProperty(\n NewClassObject,\n 'query',\n Object.getOwnPropertyDescriptor(AV.Object, 'query')\n );\n NewClassObject['new'] = function(attributes, options) {\n return new NewClassObject(attributes, options);\n };\n AV.Object._classMap[className] = NewClassObject;\n return NewClassObject;\n };\n\n // ES6 class syntax support\n Object.defineProperty(AV.Object.prototype, 'className', {\n get: function() {\n const className =\n this._className ||\n this.constructor._LCClassName ||\n this.constructor.name;\n // If someone tries to subclass \"User\", coerce it to the right type.\n if (className === 'User') {\n return '_User';\n }\n return className;\n },\n });\n\n /**\n * Register a class.\n * If a subclass ofAV.Object
is defined with your own implement\n * rather then AV.Object.extend
, the subclass must be registered.\n * @param {Function} klass A subclass of AV.Object
\n * @param {String} [name] Specify the name of the class. Useful when the class might be uglified.\n * @example\n * class Person extend AV.Object {}\n * AV.Object.register(Person);\n */\n AV.Object.register = (klass, name) => {\n if (!(klass.prototype instanceof AV.Object)) {\n throw new Error('registered class is not a subclass of AV.Object');\n }\n const className = name || klass.name;\n if (!className.length) {\n throw new Error('registered class must be named');\n }\n if (name) {\n klass._LCClassName = name;\n }\n AV.Object._classMap[className] = klass;\n };\n\n /**\n * Get a new Query of the current class\n * @name query\n * @memberof AV.Object\n * @type AV.Query\n * @readonly\n * @since v3.1.0\n * @example\n * const Post = AV.Object.extend('Post');\n * Post.query.equalTo('author', 'leancloud').find().then();\n */\n Object.defineProperty(AV.Object, 'query', {\n get() {\n return new AV.Query(this.prototype.className);\n },\n });\n\n AV.Object._findUnsavedChildren = function(objects, children, files) {\n AV._traverse(objects, function(object) {\n if (object instanceof AV.Object) {\n if (object.dirty()) {\n children.push(object);\n }\n return;\n }\n\n if (object instanceof AV.File) {\n if (!object.id) {\n files.push(object);\n }\n return;\n }\n });\n };\n\n AV.Object._canBeSerializedAsValue = function(object) {\n var canBeSerializedAsValue = true;\n\n if (object instanceof AV.Object || object instanceof AV.File) {\n canBeSerializedAsValue = !!object.id;\n } else if (_.isArray(object)) {\n AV._arrayEach(object, function(child) {\n if (!AV.Object._canBeSerializedAsValue(child)) {\n canBeSerializedAsValue = false;\n }\n });\n } else if (_.isObject(object)) {\n AV._objectEach(object, function(child) {\n if (!AV.Object._canBeSerializedAsValue(child)) {\n canBeSerializedAsValue = false;\n }\n });\n }\n\n return canBeSerializedAsValue;\n };\n\n AV.Object._deepSaveAsync = function(object, model, options) {\n var unsavedChildren = [];\n var unsavedFiles = [];\n AV.Object._findUnsavedChildren(object, unsavedChildren, unsavedFiles);\n\n unsavedFiles = _.uniq(unsavedFiles);\n\n var promise = Promise.resolve();\n _.each(unsavedFiles, function(file) {\n promise = promise.then(function() {\n return file.save();\n });\n });\n\n var objects = _.uniq(unsavedChildren);\n var remaining = _.uniq(objects);\n\n return promise\n .then(function() {\n return continueWhile(\n function() {\n return remaining.length > 0;\n },\n function() {\n // Gather up all the objects that can be saved in this batch.\n var batch = [];\n var newRemaining = [];\n AV._arrayEach(remaining, function(object) {\n if (object._canBeSerialized()) {\n batch.push(object);\n } else {\n newRemaining.push(object);\n }\n });\n remaining = newRemaining;\n\n // If we can't save any objects, there must be a circular reference.\n if (batch.length === 0) {\n return Promise.reject(\n new AVError(\n AVError.OTHER_CAUSE,\n 'Tried to save a batch with a cycle.'\n )\n );\n }\n\n // Reserve a spot in every object's save queue.\n var readyToStart = Promise.resolve(\n _.map(batch, function(object) {\n return object._allPreviousSaves || Promise.resolve();\n })\n );\n\n // Save a single batch, whether previous saves succeeded or failed.\n const bathSavePromise = readyToStart.then(() =>\n _request(\n 'batch',\n null,\n null,\n 'POST',\n {\n requests: _.map(batch, function(object) {\n var method = object.id ? 'PUT' : 'POST';\n\n var json = object._getSaveJSON();\n\n _.extend(json, object._flags);\n\n var route = 'classes';\n var className = object.className;\n var path = `/${route}/${className}`;\n if (object.className === '_User' && !object.id) {\n // Special-case user sign-up.\n path = '/users';\n }\n\n var path = `/1.1${path}`;\n if (object.id) {\n path = path + '/' + object.id;\n }\n\n object._startSave();\n\n return {\n method: method,\n path: path,\n body: json,\n params:\n options && options.fetchWhenSave\n ? { fetchWhenSave: true }\n : undefined,\n };\n }),\n },\n options\n ).then(function(response) {\n const results = _.map(batch, function(object, i) {\n if (response[i].success) {\n object._finishSave(object.parse(response[i].success));\n return object;\n }\n object._cancelSave();\n return new AVError(\n response[i].error.code,\n response[i].error.error\n );\n });\n return handleBatchResults(results);\n })\n );\n AV._arrayEach(batch, function(object) {\n object._allPreviousSaves = bathSavePromise;\n });\n return bathSavePromise;\n }\n );\n })\n .then(function() {\n return object;\n });\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/object.js","var arrayWithHoles = require(\"./arrayWithHoles.js\");\n\nvar iterableToArrayLimit = require(\"./iterableToArrayLimit.js\");\n\nvar unsupportedIterableToArray = require(\"./unsupportedIterableToArray.js\");\n\nvar nonIterableRest = require(\"./nonIterableRest.js\");\n\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}\n\nmodule.exports = _slicedToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/slicedToArray.js\n// module id = 501\n// module chunks = 0 1","var _Array$isArray = require(\"@babel/runtime-corejs3/core-js/array/is-array\");\n\nfunction _arrayWithHoles(arr) {\n if (_Array$isArray(arr)) return arr;\n}\n\nmodule.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/arrayWithHoles.js\n// module id = 502\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/array/is-array\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/array/is-array.js\n// module id = 503\n// module chunks = 0 1","module.exports = require('../../full/array/is-array');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/array/is-array.js\n// module id = 504\n// module chunks = 0 1","var parent = require('../../actual/array/is-array');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/array/is-array.js\n// module id = 505\n// module chunks = 0 1","var parent = require('../../stable/array/is-array');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/array/is-array.js\n// module id = 506\n// module chunks = 0 1","var parent = require('../../es/array/is-array');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/array/is-array.js\n// module id = 507\n// module chunks = 0 1","require('../../modules/es.array.is-array');\nvar path = require('../../internals/path');\n\nmodule.exports = path.Array.isArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/is-array.js\n// module id = 508\n// module chunks = 0 1","var $ = require('../internals/export');\nvar isArray = require('../internals/is-array');\n\n// `Array.isArray` method\n// https://tc39.es/ecma262/#sec-array.isarray\n$({ target: 'Array', stat: true }, {\n isArray: isArray\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.is-array.js\n// module id = 509\n// module chunks = 0 1","var _Symbol = require(\"@babel/runtime-corejs3/core-js/symbol\");\n\nvar _getIteratorMethod = require(\"@babel/runtime-corejs3/core-js/get-iterator-method\");\n\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof _Symbol !== \"undefined\" && _getIteratorMethod(arr) || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nmodule.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/iterableToArrayLimit.js\n// module id = 510\n// module chunks = 0 1","var _sliceInstanceProperty = require(\"@babel/runtime-corejs3/core-js/instance/slice\");\n\nvar _Array$from = require(\"@babel/runtime-corejs3/core-js/array/from\");\n\nvar arrayLikeToArray = require(\"./arrayLikeToArray.js\");\n\nfunction _unsupportedIterableToArray(o, minLen) {\n var _context;\n\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n\n var n = _sliceInstanceProperty(_context = Object.prototype.toString.call(o)).call(_context, 8, -1);\n\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return _Array$from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}\n\nmodule.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/unsupportedIterableToArray.js\n// module id = 511\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/instance/slice\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/instance/slice.js\n// module id = 512\n// module chunks = 0 1","module.exports = require('../../full/instance/slice');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/instance/slice.js\n// module id = 513\n// module chunks = 0 1","var parent = require('../../actual/instance/slice');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/instance/slice.js\n// module id = 514\n// module chunks = 0 1","var parent = require('../../stable/instance/slice');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/instance/slice.js\n// module id = 515\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/array/from\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/array/from.js\n// module id = 516\n// module chunks = 0 1","module.exports = require('../../full/array/from');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/array/from.js\n// module id = 517\n// module chunks = 0 1","var parent = require('../../actual/array/from');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/array/from.js\n// module id = 518\n// module chunks = 0 1","var parent = require('../../stable/array/from');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/array/from.js\n// module id = 519\n// module chunks = 0 1","function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}\n\nmodule.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/arrayLikeToArray.js\n// module id = 520\n// module chunks = 0 1","function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nmodule.exports = _nonIterableRest, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/nonIterableRest.js\n// module id = 521\n// module chunks = 0 1","module.exports = require(\"core-js-pure/stable/object/get-own-property-descriptor\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor.js\n// module id = 522\n// module chunks = 0 1","var parent = require('../../es/object/get-own-property-descriptor');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/object/get-own-property-descriptor.js\n// module id = 523\n// module chunks = 0 1","require('../../modules/es.object.get-own-property-descriptor');\nvar path = require('../../internals/path');\n\nvar Object = path.Object;\n\nvar getOwnPropertyDescriptor = module.exports = function getOwnPropertyDescriptor(it, key) {\n return Object.getOwnPropertyDescriptor(it, key);\n};\n\nif (Object.getOwnPropertyDescriptor.sham) getOwnPropertyDescriptor.sham = true;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/object/get-own-property-descriptor.js\n// module id = 524\n// module chunks = 0 1","var $ = require('../internals/export');\nvar fails = require('../internals/fails');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar nativeGetOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar DESCRIPTORS = require('../internals/descriptors');\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeGetOwnPropertyDescriptor(1); });\nvar FORCED = !DESCRIPTORS || FAILS_ON_PRIMITIVES;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\n$({ target: 'Object', stat: true, forced: FORCED, sham: !DESCRIPTORS }, {\n getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) {\n return nativeGetOwnPropertyDescriptor(toIndexedObject(it), key);\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.object.get-own-property-descriptor.js\n// module id = 525\n// module chunks = 0 1","const _ = require('underscore');\nconst AVError = require('./error');\n\nmodule.exports = function(AV) {\n AV.Role = AV.Object.extend(\n '_Role',\n /** @lends AV.Role.prototype */ {\n // Instance Methods\n\n /**\n * Represents a Role on the AV server. Roles represent groupings of\n * Users for the purposes of granting permissions (e.g. specifying an ACL\n * for an Object). Roles are specified by their sets of child users and\n * child roles, all of which are granted any permissions that the parent\n * role has.\n *\n * Roles must have a name (which cannot be changed after creation of the\n * role), and must specify an ACL.
\n * An AV.Role is a local representation of a role persisted to the AV\n * cloud.\n * @class AV.Role\n * @param {String} name The name of the Role to create.\n * @param {AV.ACL} acl The ACL for this role.\n */\n constructor: function(name, acl) {\n if (_.isString(name)) {\n AV.Object.prototype.constructor.call(this, null, null);\n this.setName(name);\n } else {\n AV.Object.prototype.constructor.call(this, name, acl);\n }\n if (acl) {\n if (!(acl instanceof AV.ACL)) {\n throw new TypeError('acl must be an instance of AV.ACL');\n } else {\n this.setACL(acl);\n }\n }\n },\n\n /**\n * Gets the name of the role. You can alternatively call role.get(\"name\")\n *\n * @return {String} the name of the role.\n */\n getName: function() {\n return this.get('name');\n },\n\n /**\n * Sets the name for a role. This value must be set before the role has\n * been saved to the server, and cannot be set once the role has been\n * saved.\n *\n *\n * A role's name can only contain alphanumeric characters, _, -, and\n * spaces.\n *
\n *\n *This is equivalent to calling role.set(\"name\", name)
\n *\n * @param {String} name The name of the role.\n */\n setName: function(name, options) {\n return this.set('name', name, options);\n },\n\n /**\n * Gets the AV.Relation for the AV.Users that are direct\n * children of this role. These users are granted any privileges that this\n * role has been granted (e.g. read or write access through ACLs). You can\n * add or remove users from the role through this relation.\n *\n *This is equivalent to calling role.relation(\"users\")
\n *\n * @return {AV.Relation} the relation for the users belonging to this\n * role.\n */\n getUsers: function() {\n return this.relation('users');\n },\n\n /**\n * Gets the AV.Relation for the AV.Roles that are direct\n * children of this role. These roles' users are granted any privileges that\n * this role has been granted (e.g. read or write access through ACLs). You\n * can add or remove child roles from this role through this relation.\n *\n *This is equivalent to calling role.relation(\"roles\")
\n *\n * @return {AV.Relation} the relation for the roles belonging to this\n * role.\n */\n getRoles: function() {\n return this.relation('roles');\n },\n\n /**\n * @ignore\n */\n validate: function(attrs, options) {\n if ('name' in attrs && attrs.name !== this.getName()) {\n var newName = attrs.name;\n if (this.id && this.id !== attrs.objectId) {\n // Check to see if the objectId being set matches this.id.\n // This happens during a fetch -- the id is set before calling fetch.\n // Let the name be set in this case.\n return new AVError(\n AVError.OTHER_CAUSE,\n \"A role's name can only be set before it has been saved.\"\n );\n }\n if (!_.isString(newName)) {\n return new AVError(\n AVError.OTHER_CAUSE,\n \"A role's name must be a String.\"\n );\n }\n if (!/^[0-9a-zA-Z\\-_ ]+$/.test(newName)) {\n return new AVError(\n AVError.OTHER_CAUSE,\n \"A role's name can only contain alphanumeric characters, _,\" +\n ' -, and spaces.'\n );\n }\n }\n if (AV.Object.prototype.validate) {\n return AV.Object.prototype.validate.call(this, attrs, options);\n }\n return false;\n },\n }\n );\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/role.js","const _ = require('underscore');\nconst uuid = require('uuid/v4');\nconst AVError = require('./error');\nconst { _request: AVRequest, request } = require('./request');\nconst { getAdapter } = require('./adapter');\n\nconst PLATFORM_ANONYMOUS = 'anonymous';\nconst PLATFORM_QQAPP = 'lc_qqapp';\n\nconst mergeUnionDataIntoAuthData = (defaultUnionIdPlatform = 'weixin') => (\n authData,\n unionId,\n { unionIdPlatform = defaultUnionIdPlatform, asMainAccount = false } = {}\n) => {\n if (typeof unionId !== 'string')\n throw new AVError(AVError.OTHER_CAUSE, 'unionId is not a string');\n if (typeof unionIdPlatform !== 'string')\n throw new AVError(AVError.OTHER_CAUSE, 'unionIdPlatform is not a string');\n\n return _.extend({}, authData, {\n platform: unionIdPlatform,\n unionid: unionId,\n main_account: Boolean(asMainAccount),\n });\n};\n\nmodule.exports = function(AV) {\n /**\n * @class\n *\n *An AV.User object is a local representation of a user persisted to the\n * LeanCloud server. This class is a subclass of an AV.Object, and retains the\n * same functionality of an AV.Object, but also extends it with various\n * user specific methods, like authentication, signing up, and validation of\n * uniqueness.
\n */\n AV.User = AV.Object.extend(\n '_User',\n /** @lends AV.User.prototype */ {\n // Instance Variables\n _isCurrentUser: false,\n\n // Instance Methods\n\n /**\n * Internal method to handle special fields in a _User response.\n * @private\n */\n _mergeMagicFields: function(attrs) {\n if (attrs.sessionToken) {\n this._sessionToken = attrs.sessionToken;\n delete attrs.sessionToken;\n }\n return AV.User.__super__._mergeMagicFields.call(this, attrs);\n },\n\n /**\n * Removes null values from authData (which exist temporarily for\n * unlinking)\n * @private\n */\n _cleanupAuthData: function() {\n if (!this.isCurrent()) {\n return;\n }\n var authData = this.get('authData');\n if (!authData) {\n return;\n }\n AV._objectEach(this.get('authData'), function(value, key) {\n if (!authData[key]) {\n delete authData[key];\n }\n });\n },\n\n /**\n * Synchronizes authData for all providers.\n * @private\n */\n _synchronizeAllAuthData: function() {\n var authData = this.get('authData');\n if (!authData) {\n return;\n }\n\n var self = this;\n AV._objectEach(this.get('authData'), function(value, key) {\n self._synchronizeAuthData(key);\n });\n },\n\n /**\n * Synchronizes auth data for a provider (e.g. puts the access token in the\n * right place to be used by the Facebook SDK).\n * @private\n */\n _synchronizeAuthData: function(provider) {\n if (!this.isCurrent()) {\n return;\n }\n var authType;\n if (_.isString(provider)) {\n authType = provider;\n provider = AV.User._authProviders[authType];\n } else {\n authType = provider.getAuthType();\n }\n var authData = this.get('authData');\n if (!authData || !provider) {\n return;\n }\n var success = provider.restoreAuthentication(authData[authType]);\n if (!success) {\n this.dissociateAuthData(provider);\n }\n },\n\n _handleSaveResult: function(makeCurrent) {\n // Clean up and synchronize the authData object, removing any unset values\n if (makeCurrent && !AV._config.disableCurrentUser) {\n this._isCurrentUser = true;\n }\n this._cleanupAuthData();\n this._synchronizeAllAuthData();\n // Don't keep the password around.\n delete this._serverData.password;\n this._rebuildEstimatedDataForKey('password');\n this._refreshCache();\n if (\n (makeCurrent || this.isCurrent()) &&\n !AV._config.disableCurrentUser\n ) {\n // Some old version of leanengine-node-sdk will overwrite\n // AV.User._saveCurrentUser which returns no Promise.\n // So we need a Promise wrapper.\n return Promise.resolve(AV.User._saveCurrentUser(this));\n } else {\n return Promise.resolve();\n }\n },\n\n /**\n * Unlike in the Android/iOS SDKs, logInWith is unnecessary, since you can\n * call linkWith on the user (even if it doesn't exist yet on the server).\n * @private\n */\n _linkWith: function(\n provider,\n data,\n { failOnNotExist = false, useMasterKey, sessionToken, user } = {}\n ) {\n var authType;\n if (_.isString(provider)) {\n authType = provider;\n provider = AV.User._authProviders[provider];\n } else {\n authType = provider.getAuthType();\n }\n if (data) {\n return this.save(\n { authData: { [authType]: data } },\n {\n useMasterKey,\n sessionToken,\n user,\n fetchWhenSave: !!this.get('authData'),\n _failOnNotExist: failOnNotExist,\n }\n ).then(function(model) {\n return model._handleSaveResult(true).then(function() {\n return model;\n });\n });\n } else {\n return provider\n .authenticate()\n .then(result => this._linkWith(provider, result));\n }\n },\n\n /**\n * Associate the user with a third party authData.\n * @since 3.3.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @return {Promisecurrent
.\n *\n * A username and password must be set before calling signUp.
\n *\n * @param {Object} attrs Extra fields to set on the new user, or null.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the signup\n * finishes.\n * @see AV.User.signUp\n */\n signUp: function(attrs, options) {\n var error;\n\n var username = (attrs && attrs.username) || this.get('username');\n if (!username || username === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up user with an empty name.'\n );\n throw error;\n }\n\n var password = (attrs && attrs.password) || this.get('password');\n if (!password || password === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up user with an empty password.'\n );\n throw error;\n }\n\n return this.save(attrs, options).then(function(model) {\n if (model.isAnonymous()) {\n model.unset(`authData.${PLATFORM_ANONYMOUS}`);\n model._opSetQueue = [{}];\n }\n return model._handleSaveResult(true).then(function() {\n return model;\n });\n });\n },\n\n /**\n * Signs up a new user with mobile phone and sms code.\n * You should call this instead of save for\n * new AV.Users. This will create a new AV.User on the server, and\n * also persist the session on disk so that you can access the user using\n *current
.\n *\n * A username and password must be set before calling signUp.
\n *\n * @param {Object} attrs Extra fields to set on the new user, or null.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the signup\n * finishes.\n * @see AV.User.signUpOrlogInWithMobilePhone\n * @see AV.Cloud.requestSmsCode\n */\n signUpOrlogInWithMobilePhone: function(attrs, options = {}) {\n var error;\n\n var mobilePhoneNumber =\n (attrs && attrs.mobilePhoneNumber) || this.get('mobilePhoneNumber');\n if (!mobilePhoneNumber || mobilePhoneNumber === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up or login user by mobilePhoneNumber ' +\n 'with an empty mobilePhoneNumber.'\n );\n throw error;\n }\n\n var smsCode = (attrs && attrs.smsCode) || this.get('smsCode');\n if (!smsCode || smsCode === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up or login user by mobilePhoneNumber ' +\n 'with an empty smsCode.'\n );\n throw error;\n }\n\n options._makeRequest = function(route, className, id, method, json) {\n return AVRequest('usersByMobilePhone', null, null, 'POST', json);\n };\n return this.save(attrs, options).then(function(model) {\n delete model.attributes.smsCode;\n delete model._serverData.smsCode;\n return model._handleSaveResult(true).then(function() {\n return model;\n });\n });\n },\n\n /**\n * The same with {@link AV.User.loginWithAuthData}, except that you can set attributes before login.\n * @since 3.7.0\n */\n loginWithAuthData(authData, platform, options) {\n return this._linkWith(platform, authData, options);\n },\n\n /**\n * The same with {@link AV.User.loginWithAuthDataAndUnionId}, except that you can set attributes before login.\n * @since 3.7.0\n */\n loginWithAuthDataAndUnionId(\n authData,\n platform,\n unionId,\n unionLoginOptions\n ) {\n return this.loginWithAuthData(\n mergeUnionDataIntoAuthData()(authData, unionId, unionLoginOptions),\n platform,\n unionLoginOptions\n );\n },\n\n /**\n * The same with {@link AV.User.loginWithWeapp}, except that you can set attributes before login.\n * @deprecated please use {@link AV.User#loginWithMiniApp}\n * @since 3.7.0\n * @param {Object} [options]\n * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @param {boolean} [options.preferUnionId] 当用户满足 {@link https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html 获取 UnionId 的条件} 时,是否使用 UnionId 登录。(since 3.13.0)\n * @param {string} [options.unionIdPlatform = 'weixin'] (only take effect when preferUnionId) unionId platform\n * @param {boolean} [options.asMainAccount = true] (only take effect when preferUnionId) If true, the unionId will be associated with the user.\n * @return {Promisecurrent
.\n *\n * A username and password must be set before calling logIn.
\n *\n * @see AV.User.logIn\n * @return {Promise} A promise that is fulfilled with the user when\n * the login is complete.\n */\n logIn: function() {\n var model = this;\n var request = AVRequest('login', null, null, 'POST', this.toJSON());\n return request.then(function(resp) {\n var serverAttrs = model.parse(resp);\n model._finishFetch(serverAttrs);\n return model._handleSaveResult(true).then(function() {\n if (!serverAttrs.smsCode) delete model.attributes['smsCode'];\n return model;\n });\n });\n },\n /**\n * @see AV.Object#save\n */\n save: function(arg1, arg2, arg3) {\n var attrs, options;\n if (_.isObject(arg1) || _.isNull(arg1) || _.isUndefined(arg1)) {\n attrs = arg1;\n options = arg2;\n } else {\n attrs = {};\n attrs[arg1] = arg2;\n options = arg3;\n }\n options = options || {};\n\n return AV.Object.prototype.save\n .call(this, attrs, options)\n .then(function(model) {\n return model._handleSaveResult(false).then(function() {\n return model;\n });\n });\n },\n\n /**\n * Follow a user\n * @since 0.3.0\n * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user.\n * @param {AV.User | String} options.user The target user or user's objectId to follow.\n * @param {Object} [options.attributes] key-value attributes dictionary to be used as\n * conditions of followerQuery/followeeQuery.\n * @param {AuthOptions} [authOptions]\n */\n follow: function(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n let user;\n let attributes;\n if (options.user) {\n user = options.user;\n attributes = options.attributes;\n } else {\n user = options;\n }\n var userObjectId = _.isString(user) ? user : user.id;\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n var route = 'users/' + this.id + '/friendship/' + userObjectId;\n var request = AVRequest(\n route,\n null,\n null,\n 'POST',\n AV._encode(attributes),\n authOptions\n );\n return request;\n },\n\n /**\n * Unfollow a user.\n * @since 0.3.0\n * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user.\n * @param {AV.User | String} options.user The target user or user's objectId to unfollow.\n * @param {AuthOptions} [authOptions]\n */\n unfollow: function(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n let user;\n if (options.user) {\n user = options.user;\n } else {\n user = options;\n }\n var userObjectId = _.isString(user) ? user : user.id;\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n var route = 'users/' + this.id + '/friendship/' + userObjectId;\n var request = AVRequest(route, null, null, 'DELETE', null, authOptions);\n return request;\n },\n\n /**\n * Get the user's followers and followees.\n * @since 4.8.0\n * @param {Object} [options]\n * @param {Number} [options.skip]\n * @param {Number} [options.limit]\n * @param {AuthOptions} [authOptions]\n */\n getFollowersAndFollowees: function(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n return request({\n method: 'GET',\n path: `/users/${this.id}/followersAndFollowees`,\n query: {\n skip: options && options.skip,\n limit: options && options.limit,\n include: 'follower,followee',\n keys: 'follower,followee',\n },\n authOptions,\n }).then(({ followers, followees }) => ({\n followers: followers.map(({ follower }) => AV._decode(follower)),\n followees: followees.map(({ followee }) => AV._decode(followee)),\n }));\n },\n\n /**\n *Create a follower query to query the user's followers.\n * @since 0.3.0\n * @see AV.User#followerQuery\n */\n followerQuery: function() {\n return AV.User.followerQuery(this.id);\n },\n\n /**\n *Create a followee query to query the user's followees.\n * @since 0.3.0\n * @see AV.User#followeeQuery\n */\n followeeQuery: function() {\n return AV.User.followeeQuery(this.id);\n },\n\n /**\n * @see AV.Object#fetch\n */\n fetch: function(fetchOptions, options) {\n return AV.Object.prototype.fetch\n .call(this, fetchOptions, options)\n .then(function(model) {\n return model._handleSaveResult(false).then(function() {\n return model;\n });\n });\n },\n\n /**\n * Update user's new password safely based on old password.\n * @param {String} oldPassword the old password.\n * @param {String} newPassword the new password.\n * @param {AuthOptions} options\n */\n updatePassword: function(oldPassword, newPassword, options) {\n var route = 'users/' + this.id + '/updatePassword';\n var params = {\n old_password: oldPassword,\n new_password: newPassword,\n };\n var request = AVRequest(route, null, null, 'PUT', params, options);\n return request.then(resp => {\n this._finishFetch(this.parse(resp));\n return this._handleSaveResult(true).then(() => resp);\n });\n },\n\n /**\n * Returns true ifcurrent
would return this user.\n * @see AV.User#current\n */\n isCurrent: function() {\n return this._isCurrentUser;\n },\n\n /**\n * Returns get(\"username\").\n * @return {String}\n * @see AV.Object#get\n */\n getUsername: function() {\n return this.get('username');\n },\n\n /**\n * Returns get(\"mobilePhoneNumber\").\n * @return {String}\n * @see AV.Object#get\n */\n getMobilePhoneNumber: function() {\n return this.get('mobilePhoneNumber');\n },\n\n /**\n * Calls set(\"mobilePhoneNumber\", phoneNumber, options) and returns the result.\n * @param {String} mobilePhoneNumber\n * @return {Boolean}\n * @see AV.Object#set\n */\n setMobilePhoneNumber: function(phone, options) {\n return this.set('mobilePhoneNumber', phone, options);\n },\n\n /**\n * Calls set(\"username\", username, options) and returns the result.\n * @param {String} username\n * @return {Boolean}\n * @see AV.Object#set\n */\n setUsername: function(username, options) {\n return this.set('username', username, options);\n },\n\n /**\n * Calls set(\"password\", password, options) and returns the result.\n * @param {String} password\n * @return {Boolean}\n * @see AV.Object#set\n */\n setPassword: function(password, options) {\n return this.set('password', password, options);\n },\n\n /**\n * Returns get(\"email\").\n * @return {String}\n * @see AV.Object#get\n */\n getEmail: function() {\n return this.get('email');\n },\n\n /**\n * Calls set(\"email\", email, options) and returns the result.\n * @param {String} email\n * @param {AuthOptions} options\n * @return {Boolean}\n * @see AV.Object#set\n */\n setEmail: function(email, options) {\n return this.set('email', email, options);\n },\n\n /**\n * Checks whether this user is the current user and has been authenticated.\n * @deprecated 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),\n * 如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id\n * @return (Boolean) whether this user is the current user and is logged in.\n */\n authenticated: function() {\n console.warn(\n 'DEPRECATED: 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id。'\n );\n return (\n !!this._sessionToken &&\n (!AV._config.disableCurrentUser &&\n AV.User.current() &&\n AV.User.current().id === this.id)\n );\n },\n\n /**\n * Detects if current sessionToken is valid.\n *\n * @since 2.0.0\n * @return Promise.current
.\n *\n * @param {String} username The username (or email) to log in with.\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logIn: function(username, password) {\n var user = AV.Object._create('_User');\n user._finishFetch({ username: username, password: password });\n return user.logIn();\n },\n\n /**\n * Logs in a user with a session token. On success, this saves the session\n * to disk, so you can retrieve the currently logged in user using\n * current
.\n *\n * @param {String} sessionToken The sessionToken to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n */\n become: function(sessionToken) {\n return this._fetchUserBySessionToken(sessionToken).then(user =>\n user._handleSaveResult(true).then(() => user)\n );\n },\n\n _fetchUserBySessionToken: function(sessionToken) {\n if (sessionToken === undefined) {\n return Promise.reject(\n new Error('The sessionToken cannot be undefined')\n );\n }\n\n var user = AV.Object._create('_User');\n return request({\n method: 'GET',\n path: '/users/me',\n authOptions: {\n sessionToken,\n },\n }).then(function(resp) {\n var serverAttrs = user.parse(resp);\n user._finishFetch(serverAttrs);\n return user;\n });\n },\n\n /**\n * Logs in a user with a mobile phone number and sms code sent by\n * AV.User.requestLoginSmsCode.On success, this\n * saves the session to disk, so you can retrieve the currently logged in\n * user using current
.\n *\n * @param {String} mobilePhone The user's mobilePhoneNumber\n * @param {String} smsCode The sms code sent by AV.User.requestLoginSmsCode\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logInWithMobilePhoneSmsCode: function(mobilePhone, smsCode) {\n var user = AV.Object._create('_User');\n user._finishFetch({ mobilePhoneNumber: mobilePhone, smsCode: smsCode });\n return user.logIn();\n },\n\n /**\n * Signs up or logs in a user with a mobilePhoneNumber and smsCode.\n * On success, this saves the session to disk, so you can retrieve the currently\n * logged in user using current
.\n *\n * @param {String} mobilePhoneNumber The user's mobilePhoneNumber.\n * @param {String} smsCode The sms code sent by AV.Cloud.requestSmsCode\n * @param {Object} attributes The user's other attributes such as username etc.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#signUpOrlogInWithMobilePhone\n * @see AV.Cloud.requestSmsCode\n */\n signUpOrlogInWithMobilePhone: function(\n mobilePhoneNumber,\n smsCode,\n attrs,\n options\n ) {\n attrs = attrs || {};\n attrs.mobilePhoneNumber = mobilePhoneNumber;\n attrs.smsCode = smsCode;\n var user = AV.Object._create('_User');\n return user.signUpOrlogInWithMobilePhone(attrs, options);\n },\n\n /**\n * Logs in a user with a mobile phone number and password. On success, this\n * saves the session to disk, so you can retrieve the currently logged in\n * user using current
.\n *\n * @param {String} mobilePhone The user's mobilePhoneNumber\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logInWithMobilePhone: function(mobilePhone, password) {\n var user = AV.Object._create('_User');\n user._finishFetch({\n mobilePhoneNumber: mobilePhone,\n password: password,\n });\n return user.logIn();\n },\n\n /**\n * Logs in a user with email and password.\n *\n * @since 3.13.0\n * @param {String} email The user's email.\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n */\n loginWithEmail(email, password) {\n const user = AV.Object._create('_User');\n user._finishFetch({\n email,\n password,\n });\n return user.logIn();\n },\n\n /**\n * Signs up or logs in a user with a third party auth data(AccessToken).\n * On success, this saves the session to disk, so you can retrieve the currently\n * logged in user using current
.\n *\n * @since 3.7.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @param {Object} [options]\n * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @example AV.User.loginWithAuthData({\n * openid: 'abc123',\n * access_token: '123abc',\n * expires_in: 1382686496\n * }, 'weixin').then(function(user) {\n * //Access user here\n * }).catch(function(error) {\n * //console.error(\"error: \", error);\n * });\n * @see {@link https://leancloud.cn/docs/js_guide.html#绑定第三方平台账户}\n */\n loginWithAuthData(authData, platform, options) {\n return AV.User._logInWith(platform, authData, options);\n },\n\n /**\n * @deprecated renamed to {@link AV.User.loginWithAuthData}\n */\n signUpOrlogInWithAuthData(...param) {\n console.warn(\n 'DEPRECATED: User.signUpOrlogInWithAuthData 已废弃,请使用 User#loginWithAuthData 代替'\n );\n return this.loginWithAuthData(...param);\n },\n\n /**\n * Signs up or logs in a user with a third party authData and unionId.\n * @since 3.7.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @param {string} unionId\n * @param {Object} [unionLoginOptions]\n * @param {string} [unionLoginOptions.unionIdPlatform = 'weixin'] unionId platform\n * @param {boolean} [unionLoginOptions.asMainAccount = false] If true, the unionId will be associated with the user.\n * @param {boolean} [unionLoginOptions.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @return {Promisecurrent
will return null
.\n * @return {Promise}\n */\n logOut: function() {\n if (AV._config.disableCurrentUser) {\n console.warn(\n 'AV.User.current() was disabled in multi-user environment, call logOut() from user object instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html'\n );\n return Promise.resolve(null);\n }\n\n if (AV.User._currentUser !== null) {\n AV.User._currentUser._logOutWithAll();\n AV.User._currentUser._isCurrentUser = false;\n }\n AV.User._currentUserMatchesDisk = true;\n AV.User._currentUser = null;\n return AV.localStorage\n .removeItemAsync(AV._getAVPath(AV.User._CURRENT_USER_KEY))\n .then(() => AV._refreshSubscriptionId());\n },\n\n /**\n *Create a follower query for special user to query the user's followers.\n * @param {String} userObjectId The user object id.\n * @return {AV.FriendShipQuery}\n * @since 0.3.0\n */\n followerQuery: function(userObjectId) {\n if (!userObjectId || !_.isString(userObjectId)) {\n throw new Error('Invalid user object id.');\n }\n var query = new AV.FriendShipQuery('_Follower');\n query._friendshipTag = 'follower';\n query.equalTo(\n 'user',\n AV.Object.createWithoutData('_User', userObjectId)\n );\n return query;\n },\n\n /**\n *Create a followee query for special user to query the user's followees.\n * @param {String} userObjectId The user object id.\n * @return {AV.FriendShipQuery}\n * @since 0.3.0\n */\n followeeQuery: function(userObjectId) {\n if (!userObjectId || !_.isString(userObjectId)) {\n throw new Error('Invalid user object id.');\n }\n var query = new AV.FriendShipQuery('_Followee');\n query._friendshipTag = 'followee';\n query.equalTo(\n 'user',\n AV.Object.createWithoutData('_User', userObjectId)\n );\n return query;\n },\n\n /**\n * Requests a password reset email to be sent to the specified email address\n * associated with the user account. This email allows the user to securely\n * reset their password on the AV site.\n *\n * @param {String} email The email address associated with the user that\n * forgot their password.\n * @return {Promise}\n */\n requestPasswordReset: function(email) {\n var json = { email: email };\n var request = AVRequest(\n 'requestPasswordReset',\n null,\n null,\n 'POST',\n json\n );\n return request;\n },\n\n /**\n * Requests a verify email to be sent to the specified email address\n * associated with the user account. This email allows the user to securely\n * verify their email address on the AV site.\n *\n * @param {String} email The email address associated with the user that\n * doesn't verify their email address.\n * @return {Promise}\n */\n requestEmailVerify: function(email) {\n var json = { email: email };\n var request = AVRequest('requestEmailVerify', null, null, 'POST', json);\n return request;\n },\n\n /**\n * Requests a verify sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * verify their mobile phone number by calling AV.User.verifyMobilePhone\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that doesn't verify their mobile phone number.\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestMobilePhoneVerify: function(mobilePhoneNumber, options = {}) {\n const data = {\n mobilePhoneNumber,\n };\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n var request = AVRequest(\n 'requestMobilePhoneVerify',\n null,\n null,\n 'POST',\n data,\n options\n );\n return request;\n },\n\n /**\n * Requests a reset password sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * reset their account's password by calling AV.User.resetPasswordBySmsCode\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that doesn't verify their mobile phone number.\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestPasswordResetBySmsCode: function(mobilePhoneNumber, options = {}) {\n const data = {\n mobilePhoneNumber,\n };\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n var request = AVRequest(\n 'requestPasswordResetBySmsCode',\n null,\n null,\n 'POST',\n data,\n options\n );\n return request;\n },\n\n /**\n * Requests a change mobile phone number sms code to be sent to the mobilePhoneNumber.\n * This sms code allows current user to reset it's mobilePhoneNumber by\n * calling {@link AV.User.changePhoneNumber}\n * @since 4.7.0\n * @param {String} mobilePhoneNumber\n * @param {Number} [ttl] ttl of sms code (default is 6 minutes)\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestChangePhoneNumber(mobilePhoneNumber, ttl, options) {\n const data = { mobilePhoneNumber };\n if (ttl) {\n data.ttl = options.ttl;\n }\n if (options && options.validateToken) {\n data.validate_token = options.validateToken;\n }\n return AVRequest(\n 'requestChangePhoneNumber',\n null,\n null,\n 'POST',\n data,\n options\n );\n },\n\n /**\n * Makes a call to reset user's account mobilePhoneNumber by sms code.\n * The sms code is sent by {@link AV.User.requestChangePhoneNumber}\n * @since 4.7.0\n * @param {String} mobilePhoneNumber\n * @param {String} code The sms code.\n * @return {Promise}\n */\n changePhoneNumber(mobilePhoneNumber, code) {\n const data = { mobilePhoneNumber, code };\n return AVRequest('changePhoneNumber', null, null, 'POST', data);\n },\n\n /**\n * Makes a call to reset user's account password by sms code and new password.\n * The sms code is sent by AV.User.requestPasswordResetBySmsCode.\n * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode\n * @param {String} password The new password.\n * @param {String} mobilePhoneNumber\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n resetPasswordBySmsCode: function(code, password, mobilePhoneNumber) {\n var json = { password: password, mobilePhoneNumber: mobilePhoneNumber };\n var request = AVRequest(\n 'resetPasswordBySmsCode',\n null,\n code,\n 'PUT',\n json\n );\n return request;\n },\n\n /**\n * Makes a call to verify sms code that sent by AV.User.Cloud.requestSmsCode\n * If verify successfully,the user mobilePhoneVerified attribute will be true.\n * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode\n * @param {String} mobilePhoneNumber\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n verifyMobilePhone: function(code, mobilePhoneNumber) {\n var json = { mobilePhoneNumber: mobilePhoneNumber };\n var request = AVRequest('verifyMobilePhone', null, code, 'POST', json);\n return request;\n },\n\n /**\n * Requests a logIn sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * login by AV.User.logInWithMobilePhoneSmsCode function.\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that want to login by AV.User.logInWithMobilePhoneSmsCode\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestLoginSmsCode: function(mobilePhoneNumber, options = {}) {\n const data = {\n mobilePhoneNumber,\n };\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n var request = AVRequest(\n 'requestLoginSmsCode',\n null,\n null,\n 'POST',\n data,\n options\n );\n return request;\n },\n\n /**\n * Retrieves the currently logged in AVUser with a valid session,\n * either from memory or localStorage, if necessary.\n * @return {Promise.AV.Query defines a query that is used to fetch AV.Objects. The\n * most common use case is finding all objects that match a query through the\n * find
method. For example, this sample code fetches all objects\n * of class MyClass
. It calls a different function depending on\n * whether the fetch succeeded or not.\n *\n *
\n * var query = new AV.Query(MyClass);\n * query.find().then(function(results) {\n * // results is an array of AV.Object.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n *\n *
An AV.Query can also be used to retrieve a single object whose id is\n * known, through the get method. For example, this sample code fetches an\n * object of class MyClass
and id myId
. It calls a\n * different function depending on whether the fetch succeeded or not.\n *\n *
\n * var query = new AV.Query(MyClass);\n * query.get(myId).then(function(object) {\n * // object is an instance of AV.Object.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n *\n *
An AV.Query can also be used to count the number of objects that match\n * the query without retrieving all of those objects. For example, this\n * sample code counts the number of objects of the class MyClass
\n *
\n * var query = new AV.Query(MyClass);\n * query.count().then(function(number) {\n * // There are number instances of MyClass.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n */\n AV.Query = function(objectClass) {\n if (_.isString(objectClass)) {\n objectClass = AV.Object._getSubclass(objectClass);\n }\n\n this.objectClass = objectClass;\n\n this.className = objectClass.prototype.className;\n\n this._where = {};\n this._include = [];\n this._select = [];\n this._limit = -1; // negative limit means, do not send a limit\n this._skip = 0;\n this._defaultParams = {};\n };\n\n /**\n * Constructs a AV.Query that is the OR of the passed in queries. For\n * example:\n *
var compoundQuery = AV.Query.or(query1, query2, query3);\n *\n * will create a compoundQuery that is an or of the query1, query2, and\n * query3.\n * @param {...AV.Query} var_args The list of queries to OR.\n * @return {AV.Query} The query that is the OR of the passed in queries.\n */\n AV.Query.or = function() {\n var queries = _.toArray(arguments);\n var className = null;\n AV._arrayEach(queries, function(q) {\n if (_.isNull(className)) {\n className = q.className;\n }\n\n if (className !== q.className) {\n throw new Error('All queries must be for the same class');\n }\n });\n var query = new AV.Query(className);\n query._orQuery(queries);\n return query;\n };\n\n /**\n * Constructs a AV.Query that is the AND of the passed in queries. For\n * example:\n *
var compoundQuery = AV.Query.and(query1, query2, query3);\n *\n * will create a compoundQuery that is an 'and' of the query1, query2, and\n * query3.\n * @param {...AV.Query} var_args The list of queries to AND.\n * @return {AV.Query} The query that is the AND of the passed in queries.\n */\n AV.Query.and = function() {\n var queries = _.toArray(arguments);\n var className = null;\n AV._arrayEach(queries, function(q) {\n if (_.isNull(className)) {\n className = q.className;\n }\n\n if (className !== q.className) {\n throw new Error('All queries must be for the same class');\n }\n });\n var query = new AV.Query(className);\n query._andQuery(queries);\n return query;\n };\n\n /**\n * Retrieves a list of AVObjects that satisfy the CQL.\n * CQL syntax please see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.\n *\n * @param {String} cql A CQL string, see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.\n * @param {Array} pvalues An array contains placeholder values.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is resolved with the results when\n * the query completes.\n */\n AV.Query.doCloudQuery = function(cql, pvalues, options) {\n var params = { cql: cql };\n if (_.isArray(pvalues)) {\n params.pvalues = pvalues;\n } else {\n options = pvalues;\n }\n\n var request = _request('cloudQuery', null, null, 'GET', params, options);\n return request.then(function(response) {\n //query to process results.\n var query = new AV.Query(response.className);\n var results = _.map(response.results, function(json) {\n var obj = query._newObject(response);\n if (obj._finishFetch) {\n obj._finishFetch(query._processResult(json), true);\n }\n return obj;\n });\n return {\n results: results,\n count: response.count,\n className: response.className,\n };\n });\n };\n\n /**\n * Return a query with conditions from json.\n * This can be useful to send a query from server side to client side.\n * @since 4.0.0\n * @param {Object} json from {@link AV.Query#toJSON}\n * @return {AV.Query}\n */\n AV.Query.fromJSON = ({\n className,\n where,\n include,\n select,\n includeACL,\n limit,\n skip,\n order,\n }) => {\n if (typeof className !== 'string') {\n throw new TypeError('Invalid Query JSON, className must be a String.');\n }\n const query = new AV.Query(className);\n _.extend(query, {\n _where: where,\n _include: include,\n _select: select,\n _includeACL: includeACL,\n _limit: limit,\n _skip: skip,\n _order: order,\n });\n return query;\n };\n\n AV.Query._extend = AV._extend;\n\n _.extend(\n AV.Query.prototype,\n /** @lends AV.Query.prototype */ {\n //hook to iterate result. Added by dennis
\n * Some functions are only available from Cloud Code.\n *
\n *\n * @namespace\n * @borrows AV.Captcha.request as requestCaptcha\n */\n AV.Cloud = AV.Cloud || {};\n\n _.extend(\n AV.Cloud,\n /** @lends AV.Cloud */ {\n /**\n * Makes a call to a cloud function.\n * @param {String} name The function name.\n * @param {Object} [data] The parameters to send to the cloud function.\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n run(name, data, options) {\n return request({\n service: 'engine',\n method: 'POST',\n path: `/functions/${name}`,\n data: AV._encode(data, null, true),\n authOptions: options,\n }).then(resp => {\n return AV._decode(resp).result;\n });\n },\n\n /**\n * Makes a call to a cloud function, you can send {AV.Object} as param or a field of param; the response\n * from server will also be parsed as an {AV.Object}, array of {AV.Object}, or object includes {AV.Object}\n * @param {String} name The function name.\n * @param {Object} [data] The parameters to send to the cloud function.\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result of the function.\n */\n rpc(name, data, options) {\n if (_.isArray(data)) {\n return Promise.reject(\n new Error(\n \"Can't pass Array as the param of rpc function in JavaScript SDK.\"\n )\n );\n }\n\n return request({\n service: 'engine',\n method: 'POST',\n path: `/call/${name}`,\n data: AV._encodeObjectOrArray(data),\n authOptions: options,\n }).then(resp => {\n return AV._decode(resp).result;\n });\n },\n\n /**\n * Make a call to request server date time.\n * @return {Promise.Send a status from current signined user to other user's private status inbox.
\n * @since 0.3.0\n * @param {AV.Status} status A status object to be send to followers.\n * @param {String} target The target user or user's objectId.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the send\n * completes.\n * @example\n * // send a private status to user '52e84e47e4b0f8de283b079b'\n * var status = new AVStatus('image url', 'a message');\n * AV.Status.sendPrivateStatus(status, '52e84e47e4b0f8de283b079b').then(function(){\n * //send status successfully.\n * }, function(err){\n * //an error threw.\n * console.dir(err);\n * });\n */\n AV.Status.sendPrivateStatus = function(status, target, options = {}) {\n if (!getSessionToken(options) && !AV.User.current()) {\n throw new Error('Please signin an user.');\n }\n if (!target) {\n throw new Error('Invalid target user.');\n }\n var userObjectId = _.isString(target) ? target : target.id;\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n return getUserPointer(options).then(currUser => {\n var query = {};\n query.className = '_User';\n query.where = { objectId: userObjectId };\n var data = {};\n data.query = query;\n status.data = status.data || {};\n status.data.source = status.data.source || currUser;\n data.data = status._getDataJSON();\n data.inboxType = 'private';\n status.inboxType = 'private';\n\n var request = AVRequest('statuses', null, null, 'POST', data, options);\n return request.then(function(response) {\n status.id = response.objectId;\n status.createdAt = AV._parseDate(response.createdAt);\n return status;\n });\n });\n };\n\n /**\n * Count unread statuses in someone's inbox.\n * @since 0.3.0\n * @param {AV.User} owner The status owner.\n * @param {String} inboxType The inbox type, 'default' by default.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the count\n * completes.\n * @example\n * AV.Status.countUnreadStatuses(AV.User.current()).then(function(response){\n * console.log(response.unread); //unread statuses number.\n * console.log(response.total); //total statuses number.\n * });\n */\n AV.Status.countUnreadStatuses = function(\n owner,\n inboxType = 'default',\n options = {}\n ) {\n if (!_.isString(inboxType)) options = inboxType;\n if (!getSessionToken(options) && owner == null && !AV.User.current()) {\n throw new Error('Please signin an user or pass the owner objectId.');\n }\n return Promise.resolve(owner || getUser(options)).then(owner => {\n var params = {};\n params.inboxType = AV._encode(inboxType);\n params.owner = AV._encode(owner);\n return AVRequest(\n 'subscribe/statuses/count',\n null,\n null,\n 'GET',\n params,\n options\n );\n });\n };\n\n /**\n * reset unread statuses count in someone's inbox.\n * @since 2.1.0\n * @param {AV.User} owner The status owner.\n * @param {String} inboxType The inbox type, 'default' by default.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the reset\n * completes.\n * @example\n * AV.Status.resetUnreadCount(AV.User.current()).then(function(response){\n * console.log(response.unread); //unread statuses number.\n * console.log(response.total); //total statuses number.\n * });\n */\n AV.Status.resetUnreadCount = function(\n owner,\n inboxType = 'default',\n options = {}\n ) {\n if (!_.isString(inboxType)) options = inboxType;\n if (!getSessionToken(options) && owner == null && !AV.User.current()) {\n throw new Error('Please signin an user or pass the owner objectId.');\n }\n return Promise.resolve(owner || getUser(options)).then(owner => {\n var params = {};\n params.inboxType = AV._encode(inboxType);\n params.owner = AV._encode(owner);\n return AVRequest(\n 'subscribe/statuses/resetUnreadCount',\n null,\n null,\n 'POST',\n params,\n options\n );\n });\n };\n\n /**\n * Create a status query to find someone's published statuses.\n * @since 0.3.0\n * @param {AV.User} source The status source, typically the publisher.\n * @return {AV.Query} The query object for status.\n * @example\n * //Find current user's published statuses.\n * var query = AV.Status.statusQuery(AV.User.current());\n * query.find().then(function(statuses){\n * //process statuses\n * });\n */\n AV.Status.statusQuery = function(source) {\n var query = new AV.Query('_Status');\n if (source) {\n query.equalTo('source', source);\n }\n return query;\n };\n\n /**\n *AV.InboxQuery defines a query that is used to fetch somebody's inbox statuses.
\n * @class\n */\n AV.InboxQuery = AV.Query._extend(\n /** @lends AV.InboxQuery.prototype */ {\n _objectClass: AV.Status,\n _sinceId: 0,\n _maxId: 0,\n _inboxType: 'default',\n _owner: null,\n _newObject: function() {\n return new AV.Status();\n },\n _createRequest: function(params, options) {\n return AV.InboxQuery.__super__._createRequest.call(\n this,\n params,\n options,\n '/subscribe/statuses'\n );\n },\n\n /**\n * Sets the messageId of results to skip before returning any results.\n * This is useful for pagination.\n * Default is zero.\n * @param {Number} n the mesage id.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n sinceId: function(id) {\n this._sinceId = id;\n return this;\n },\n /**\n * Sets the maximal messageId of results。\n * This is useful for pagination.\n * Default is zero that is no limition.\n * @param {Number} n the mesage id.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n maxId: function(id) {\n this._maxId = id;\n return this;\n },\n /**\n * Sets the owner of the querying inbox.\n * @param {AV.User} owner The inbox owner.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n owner: function(owner) {\n this._owner = owner;\n return this;\n },\n /**\n * Sets the querying inbox type.default is 'default'.\n * @param {String} type The inbox type.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n inboxType: function(type) {\n this._inboxType = type;\n return this;\n },\n _getParams: function() {\n var params = AV.InboxQuery.__super__._getParams.call(this);\n params.owner = AV._encode(this._owner);\n params.inboxType = AV._encode(this._inboxType);\n params.sinceId = AV._encode(this._sinceId);\n params.maxId = AV._encode(this._maxId);\n return params;\n },\n }\n );\n\n /**\n * Create a inbox status query to find someone's inbox statuses.\n * @since 0.3.0\n * @param {AV.User} owner The inbox's owner\n * @param {String} inboxType The inbox type,'default' by default.\n * @return {AV.InboxQuery} The inbox query object.\n * @see AV.InboxQuery\n * @example\n * //Find current user's default inbox statuses.\n * var query = AV.Status.inboxQuery(AV.User.current());\n * //find the statuses after the last message id\n * query.sinceId(lastMessageId);\n * query.find().then(function(statuses){\n * //process statuses\n * });\n */\n AV.Status.inboxQuery = function(owner, inboxType) {\n var query = new AV.InboxQuery(AV.Status);\n if (owner) {\n query._owner = owner;\n }\n if (inboxType) {\n query._inboxType = inboxType;\n }\n return query;\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/status.js","const _ = require('underscore');\nconst AVRequest = require('./request')._request;\n\nmodule.exports = function(AV) {\n /**\n * A builder to generate sort string for app searching.For example:\n * @class\n * @since 0.5.1\n * @example\n * var builder = new AV.SearchSortBuilder();\n * builder.ascending('key1').descending('key2','max');\n * var query = new AV.SearchQuery('Player');\n * query.sortBy(builder);\n * query.find().then();\n */\n AV.SearchSortBuilder = function() {\n this._sortFields = [];\n };\n\n _.extend(\n AV.SearchSortBuilder.prototype,\n /** @lends AV.SearchSortBuilder.prototype */ {\n _addField: function(key, order, mode, missing) {\n var field = {};\n field[key] = {\n order: order || 'asc',\n mode: mode || 'avg',\n missing: '_' + (missing || 'last'),\n };\n this._sortFields.push(field);\n return this;\n },\n\n /**\n * Sorts the results in ascending order by the given key and options.\n *\n * @param {String} key The key to order by.\n * @param {String} mode The sort mode, default is 'avg', you can choose\n * 'max' or 'min' too.\n * @param {String} missing The missing key behaviour, default is 'last',\n * you can choose 'first' too.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n ascending: function(key, mode, missing) {\n return this._addField(key, 'asc', mode, missing);\n },\n\n /**\n * Sorts the results in descending order by the given key and options.\n *\n * @param {String} key The key to order by.\n * @param {String} mode The sort mode, default is 'avg', you can choose\n * 'max' or 'min' too.\n * @param {String} missing The missing key behaviour, default is 'last',\n * you can choose 'first' too.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n descending: function(key, mode, missing) {\n return this._addField(key, 'desc', mode, missing);\n },\n\n /**\n * Add a proximity based constraint for finding objects with key point\n * values near the point given.\n * @param {String} key The key that the AV.GeoPoint is stored in.\n * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.\n * @param {Object} options The other options such as mode,order, unit etc.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n whereNear: function(key, point, options) {\n options = options || {};\n var field = {};\n var geo = {\n lat: point.latitude,\n lon: point.longitude,\n };\n var m = {\n order: options.order || 'asc',\n mode: options.mode || 'avg',\n unit: options.unit || 'km',\n };\n m[key] = geo;\n field['_geo_distance'] = m;\n\n this._sortFields.push(field);\n return this;\n },\n\n /**\n * Build a sort string by configuration.\n * @return {String} the sort string.\n */\n build: function() {\n return JSON.stringify(AV._encode(this._sortFields));\n },\n }\n );\n\n /**\n * App searching query.Use just like AV.Query:\n *\n * Visit App Searching Guide\n * for more details.\n * @class\n * @since 0.5.1\n * @example\n * var query = new AV.SearchQuery('Player');\n * query.queryString('*');\n * query.find().then(function(results) {\n * console.log('Found %d objects', query.hits());\n * //Process results\n * });\n */\n AV.SearchQuery = AV.Query._extend(\n /** @lends AV.SearchQuery.prototype */ {\n _sid: null,\n _hits: 0,\n _queryString: null,\n _highlights: null,\n _sortBuilder: null,\n _clazz: null,\n\n constructor: function(className) {\n if (className) {\n this._clazz = className;\n } else {\n className = '__INVALID_CLASS';\n }\n AV.Query.call(this, className);\n },\n\n _createRequest: function(params, options) {\n return AVRequest(\n 'search/select',\n null,\n null,\n 'GET',\n params || this._getParams(),\n options\n );\n },\n\n /**\n * Sets the sid of app searching query.Default is null.\n * @param {String} sid Scroll id for searching.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n sid: function(sid) {\n this._sid = sid;\n return this;\n },\n\n /**\n * Sets the query string of app searching.\n * @param {String} q The query string.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n queryString: function(q) {\n this._queryString = q;\n return this;\n },\n\n /**\n * Sets the highlight fields. Such as\n *\n * query.highlights('title');\n * //or pass an array.\n * query.highlights(['title', 'content'])\n *
\n * @param {String|String[]} highlights a list of fields.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n highlights: function(highlights) {\n var objects;\n if (highlights && _.isString(highlights)) {\n objects = _.toArray(arguments);\n } else {\n objects = highlights;\n }\n this._highlights = objects;\n return this;\n },\n\n /**\n * Sets the sort builder for this query.\n * @see AV.SearchSortBuilder\n * @param { AV.SearchSortBuilder} builder The sort builder.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n *\n */\n sortBy: function(builder) {\n this._sortBuilder = builder;\n return this;\n },\n\n /**\n * Returns the number of objects that match this query.\n * @return {Number}\n */\n hits: function() {\n if (!this._hits) {\n this._hits = 0;\n }\n return this._hits;\n },\n\n _processResult: function(json) {\n delete json['className'];\n delete json['_app_url'];\n delete json['_deeplink'];\n return json;\n },\n\n /**\n * Returns true when there are more documents can be retrieved by this\n * query instance, you can call find function to get more results.\n * @see AV.SearchQuery#find\n * @return {Boolean}\n */\n hasMore: function() {\n return !this._hitEnd;\n },\n\n /**\n * Reset current query instance state(such as sid, hits etc) except params\n * for a new searching. After resetting, hasMore() will return true.\n */\n reset: function() {\n this._hitEnd = false;\n this._sid = null;\n this._hits = 0;\n },\n\n /**\n * Retrieves a list of AVObjects that satisfy this query.\n * Either options.success or options.error is called when the find\n * completes.\n *\n * @see AV.Query#find\n * @param {AuthOptions} options\n * @return {Promise} A promise that is resolved with the results when\n * the query completes.\n */\n find: function(options) {\n var self = this;\n\n var request = this._createRequest(undefined, options);\n\n return request.then(function(response) {\n //update sid for next querying.\n if (response.sid) {\n self._oldSid = self._sid;\n self._sid = response.sid;\n } else {\n self._sid = null;\n self._hitEnd = true;\n }\n self._hits = response.hits || 0;\n\n return _.map(response.results, function(json) {\n if (json.className) {\n response.className = json.className;\n }\n var obj = self._newObject(response);\n obj.appURL = json['_app_url'];\n obj._finishFetch(self._processResult(json), true);\n return obj;\n });\n });\n },\n\n _getParams: function() {\n var params = AV.SearchQuery.__super__._getParams.call(this);\n delete params.where;\n if (this._clazz) {\n params.clazz = this.className;\n }\n if (this._sid) {\n params.sid = this._sid;\n }\n if (!this._queryString) {\n throw new Error('Please set query string.');\n } else {\n params.q = this._queryString;\n }\n if (this._highlights) {\n params.highlights = this._highlights.join(',');\n }\n if (this._sortBuilder && params.order) {\n throw new Error('sort and order can not be set at same time.');\n }\n if (this._sortBuilder) {\n params.sort = this._sortBuilder.build();\n }\n\n return params;\n },\n }\n );\n};\n\n/**\n * Sorts the results in ascending order by the given key.\n *\n * @method AV.SearchQuery#ascending\n * @param {String} key The key to order by.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Also sorts the results in ascending order by the given key. The previous sort keys have\n * precedence over this key.\n *\n * @method AV.SearchQuery#addAscending\n * @param {String} key The key to order by\n * @return {AV.SearchQuery} Returns the query so you can chain this call.\n */\n/**\n * Sorts the results in descending order by the given key.\n *\n * @method AV.SearchQuery#descending\n * @param {String} key The key to order by.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Also sorts the results in descending order by the given key. The previous sort keys have\n * precedence over this key.\n *\n * @method AV.SearchQuery#addDescending\n * @param {String} key The key to order by\n * @return {AV.SearchQuery} Returns the query so you can chain this call.\n */\n/**\n * Include nested AV.Objects for the provided key. You can use dot\n * notation to specify which fields in the included object are also fetch.\n * @method AV.SearchQuery#include\n * @param {String[]} keys The name of the key to include.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Sets the number of results to skip before returning any results.\n * This is useful for pagination.\n * Default is to skip zero results.\n * @method AV.SearchQuery#skip\n * @param {Number} n the number of results to skip.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Sets the limit of the number of results to return. The default limit is\n * 100, with a maximum of 1000 results being returned at a time.\n * @method AV.SearchQuery#limit\n * @param {Number} n the number of results to limit to.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n\n\n\n// WEBPACK FOOTER //\n// ./src/search.js","const _ = require('underscore');\nconst AVError = require('./error');\nconst { request } = require('./request');\n\nmodule.exports = function(AV) {\n /**\n * 包含了使用了 LeanCloud\n * 离线数据分析功能的函数。\n * \n * 仅在云引擎运行环境下有效。\n *
\n * @namespace\n */\n AV.Insight = AV.Insight || {};\n\n _.extend(\n AV.Insight,\n /** @lends AV.Insight */ {\n /**\n * 开始一个 Insight 任务。结果里将返回 Job id,你可以拿得到的 id 使用\n * AV.Insight.JobQuery 查询任务状态和结果。\n * @param {Object} jobConfig 任务配置的 JSON 对象,例如:\n * { \"sql\" : \"select count(*) as c,gender from _User group by gender\",\n * \"saveAs\": {\n * \"className\" : \"UserGender\",\n * \"limit\": 1\n * }\n * }\n *
\n * sql 指定任务执行的 SQL 语句, saveAs(可选) 指定将结果保存在哪张表里,limit 最大 1000。\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n startJob: function(jobConfig, options) {\n if (!jobConfig || !jobConfig.sql) {\n throw new Error('Please provide the sql to run the job.');\n }\n var data = {\n jobConfig: jobConfig,\n appId: AV.applicationId,\n };\n return request({\n path: '/bigquery/jobs',\n method: 'POST',\n data: AV._encode(data, null, true),\n authOptions: options,\n signKey: false,\n }).then(resp => AV._decode(resp).id);\n },\n\n /**\n * 监听 Insight 任务事件(未来推出独立部署的离线分析服务后开放)\n * \n * 仅在云引擎运行环境下有效。\n *
\n * @param {String} event 监听的事件,目前尚不支持。\n * @param {Function} 监听回调函数,接收 (err, id) 两个参数,err 表示错误信息,\n * id 表示任务 id。接下来你可以拿这个 id 使用AV.Insight.JobQuery 查询任务状态和结果。\n *\n */\n on: function(event, cb) {},\n }\n );\n\n /**\n * 创建一个对象,用于查询 Insight 任务状态和结果。\n * @class\n * @param {String} id 任务 id\n * @since 0.5.5\n */\n AV.Insight.JobQuery = function(id, className) {\n if (!id) {\n throw new Error('Please provide the job id.');\n }\n this.id = id;\n this.className = className;\n this._skip = 0;\n this._limit = 100;\n };\n\n _.extend(\n AV.Insight.JobQuery.prototype,\n /** @lends AV.Insight.JobQuery.prototype */ {\n /**\n * Sets the number of results to skip before returning any results.\n * This is useful for pagination.\n * Default is to skip zero results.\n * @param {Number} n the number of results to skip.\n * @return {AV.Query} Returns the query, so you can chain this call.\n */\n skip: function(n) {\n this._skip = n;\n return this;\n },\n\n /**\n * Sets the limit of the number of results to return. The default limit is\n * 100, with a maximum of 1000 results being returned at a time.\n * @param {Number} n the number of results to limit to.\n * @return {AV.Query} Returns the query, so you can chain this call.\n */\n limit: function(n) {\n this._limit = n;\n return this;\n },\n\n /**\n * 查询任务状态和结果,任务结果为一个 JSON 对象,包括 status 表示任务状态, totalCount 表示总数,\n * results 数组表示任务结果数组,previewCount 表示可以返回的结果总数,任务的开始和截止时间\n * startTime、endTime 等信息。\n *\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n *\n */\n find: function(options) {\n var params = {\n skip: this._skip,\n limit: this._limit,\n };\n\n return request({\n path: `/bigquery/jobs/${this.id}`,\n method: 'GET',\n query: params,\n authOptions: options,\n signKey: false,\n }).then(function(response) {\n if (response.error) {\n return Promise.reject(new AVError(response.code, response.error));\n }\n return Promise.resolve(response);\n });\n },\n }\n );\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/insight.js","const _ = require('underscore');\nconst { request: LCRequest } = require('./request');\nconst { getSessionToken } = require('./utils');\n\nmodule.exports = function(AV) {\n const getUserWithSessionToken = authOptions => {\n if (authOptions.user) {\n if (!authOptions.user._sessionToken) {\n throw new Error('authOptions.user is not signed in.');\n }\n return Promise.resolve(authOptions.user);\n }\n if (authOptions.sessionToken) {\n return AV.User._fetchUserBySessionToken(authOptions.sessionToken);\n }\n return AV.User.currentAsync();\n };\n\n const getSessionTokenAsync = authOptions => {\n const sessionToken = getSessionToken(authOptions);\n if (sessionToken) {\n return Promise.resolve(sessionToken);\n }\n return AV.User.currentAsync().then(user => {\n if (user) {\n return user.getSessionToken();\n }\n });\n };\n\n /**\n * Contains functions to deal with Friendship in LeanCloud.\n * @class\n */\n AV.Friendship = {\n /**\n * Request friendship.\n * @since 4.8.0\n * @param {String | AV.User | Object} options if an AV.User or string is given, it will be used as the friend.\n * @param {AV.User | string} options.friend The friend (or friend's objectId) to follow.\n * @param {Object} [options.attributes] key-value attributes dictionary to be used as conditions of followeeQuery.\n * @param {AuthOptions} [authOptions]\n * @return {PromiseAn AV.Conversation is a local representation of a LeanCloud realtime's\n * conversation. This class is a subclass of AV.Object, and retains the\n * same functionality of an AV.Object, but also extends it with various\n * conversation specific methods, like get members, creators of this conversation.\n *
\n *\n * @class AV.Conversation\n * @param {String} name The name of the Role to create.\n * @param {Object} [options]\n * @param {Boolean} [options.isSystem] Set this conversation as system conversation.\n * @param {Boolean} [options.isTransient] Set this conversation as transient conversation.\n */\nmodule.exports = AV.Object.extend(\n '_Conversation',\n /** @lends AV.Conversation.prototype */ {\n constructor(name, options = {}) {\n AV.Object.prototype.constructor.call(this, null, null);\n this.set('name', name);\n if (options.isSystem !== undefined) {\n this.set('sys', options.isSystem ? true : false);\n }\n if (options.isTransient !== undefined) {\n this.set('tr', options.isTransient ? true : false);\n }\n },\n /**\n * Get current conversation's creator.\n *\n * @return {String}\n */\n getCreator() {\n return this.get('c');\n },\n\n /**\n * Get the last message's time.\n *\n * @return {Date}\n */\n getLastMessageAt() {\n return this.get('lm');\n },\n\n /**\n * Get this conversation's members\n *\n * @return {String[]}\n */\n getMembers() {\n return this.get('m');\n },\n\n /**\n * Add a member to this conversation\n *\n * @param {String} member\n */\n addMember(member) {\n return this.add('m', member);\n },\n\n /**\n * Get this conversation's members who set this conversation as muted.\n *\n * @return {String[]}\n */\n getMutedMembers() {\n return this.get('mu');\n },\n\n /**\n * Get this conversation's name field.\n *\n * @return String\n */\n getName() {\n return this.get('name');\n },\n\n /**\n * Returns true if this conversation is transient conversation.\n *\n * @return {Boolean}\n */\n isTransient() {\n return this.get('tr');\n },\n\n /**\n * Returns true if this conversation is system conversation.\n *\n * @return {Boolean}\n */\n isSystem() {\n return this.get('sys');\n },\n\n /**\n * Send realtime message to this conversation, using HTTP request.\n *\n * @param {String} fromClient Sender's client id.\n * @param {String|Object} message The message which will send to conversation.\n * It could be a raw string, or an object with a `toJSON` method, like a\n * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息}\n * @param {Object} [options]\n * @param {Boolean} [options.transient] Whether send this message as transient message or not.\n * @param {String[]} [options.toClients] Ids of clients to send to. This option can be used only in system conversation.\n * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容}\n * @param {AuthOptions} [authOptions]\n * @return {Promise}\n */\n send(fromClient, message, options = {}, authOptions = {}) {\n const data = {\n from_peer: fromClient,\n conv_id: this.id,\n transient: false,\n message: serializeMessage(message),\n };\n if (options.toClients !== undefined) {\n data.to_peers = options.toClients;\n }\n if (options.transient !== undefined) {\n data.transient = options.transient ? true : false;\n }\n if (options.pushData !== undefined) {\n data.push_data = options.pushData;\n }\n return _request('rtm', 'messages', null, 'POST', data, authOptions);\n },\n\n /**\n * Send realtime broadcast message to all clients, via this conversation, using HTTP request.\n *\n * @param {String} fromClient Sender's client id.\n * @param {String|Object} message The message which will send to conversation.\n * It could be a raw string, or an object with a `toJSON` method, like a\n * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息}.\n * @param {Object} [options]\n * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容}.\n * @param {Object} [options.validTill] The message will valid till this time.\n * @param {AuthOptions} [authOptions]\n * @return {Promise}\n */\n broadcast(fromClient, message, options = {}, authOptions = {}) {\n const data = {\n from_peer: fromClient,\n conv_id: this.id,\n message: serializeMessage(message),\n };\n if (options.pushData !== undefined) {\n data.push = options.pushData;\n }\n if (options.validTill !== undefined) {\n let ts = options.validTill;\n if (_.isDate(ts)) {\n ts = ts.getTime();\n }\n options.valid_till = ts;\n }\n return _request('rtm', 'broadcast', null, 'POST', data, authOptions);\n },\n }\n);\n\n\n\n// WEBPACK FOOTER //\n// ./src/conversation.js","const _ = require('underscore');\nconst { request } = require('./request');\nconst { ensureArray, parseDate } = require('./utils');\nconst AV = require('./av');\n\n/**\n * The version change interval for Leaderboard\n * @enum\n */\nAV.LeaderboardVersionChangeInterval = {\n NEVER: 'never',\n DAY: 'day',\n WEEK: 'week',\n MONTH: 'month',\n};\n\n/**\n * The order of the leaderboard results\n * @enum\n */\nAV.LeaderboardOrder = {\n ASCENDING: 'ascending',\n DESCENDING: 'descending',\n};\n\n/**\n * The update strategy for Leaderboard\n * @enum\n */\nAV.LeaderboardUpdateStrategy = {\n /** Only keep the best statistic. If the leaderboard is in descending order, the best statistic is the highest one. */\n BETTER: 'better',\n /** Keep the last updated statistic */\n LAST: 'last',\n /** Keep the sum of all updated statistics */\n SUM: 'sum',\n};\n\n/**\n * @typedef {Object} Ranking\n * @property {number} rank Starts at 0\n * @property {number} value the statistic value of this ranking\n * @property {AV.User} user The user of this ranking\n * @property {Statistic[]} [includedStatistics] Other statistics of the user, specified by the `includeStatistic` option of `AV.Leaderboard.getResults()`\n */\n\n/**\n * @typedef {Object} LeaderboardArchive\n * @property {string} statisticName\n * @property {number} version version of the leaderboard\n * @property {string} status\n * @property {string} url URL for the downloadable archive\n * @property {Date} activatedAt time when this version became active\n * @property {Date} deactivatedAt time when this version was deactivated by a version incrementing\n */\n\n/**\n * @class\n */\nfunction Statistic({ name, value, version }) {\n /**\n * @type {string}\n */\n this.name = name;\n /**\n * @type {number}\n */\n this.value = value;\n /**\n * @type {number?}\n */\n this.version = version;\n}\n\nconst parseStatisticData = statisticData => {\n const { statisticName: name, statisticValue: value, version } = AV._decode(\n statisticData\n );\n return new Statistic({ name, value, version });\n};\n\n/**\n * @class\n */\nAV.Leaderboard = function Leaderboard(statisticName) {\n /**\n * @type {string}\n */\n this.statisticName = statisticName;\n /**\n * @type {AV.LeaderboardOrder}\n */\n this.order = undefined;\n /**\n * @type {AV.LeaderboardUpdateStrategy}\n */\n this.updateStrategy = undefined;\n /**\n * @type {AV.LeaderboardVersionChangeInterval}\n */\n this.versionChangeInterval = undefined;\n /**\n * @type {number}\n */\n this.version = undefined;\n /**\n * @type {Date?}\n */\n this.nextResetAt = undefined;\n /**\n * @type {Date?}\n */\n this.createdAt = undefined;\n};\nconst Leaderboard = AV.Leaderboard;\n\n/**\n * Create an instance of Leaderboard for the give statistic name.\n * @param {string} statisticName\n * @return {AV.Leaderboard}\n */\nAV.Leaderboard.createWithoutData = statisticName =>\n new Leaderboard(statisticName);\n/**\n * (masterKey required) Create a new Leaderboard.\n * @param {Object} options\n * @param {string} options.statisticName\n * @param {AV.LeaderboardOrder} options.order\n * @param {AV.LeaderboardVersionChangeInterval} [options.versionChangeInterval] default to WEEK\n * @param {AV.LeaderboardUpdateStrategy} [options.updateStrategy] default to BETTER\n * @param {AuthOptions} [authOptions]\n * @return {PromiseAvailable in Cloud Code and Node.js only. + *
+ */ + + AV.Cloud.useMasterKey = function () { + AV._config.useMasterKey = true; + }; +} +/** + * Call this method to set production environment variable. + * @function AV.setProduction + * @param {Boolean} production True is production environment,and + * it's true by default. + */ + + +AV.setProduction = function (production) { + if (!isNullOrUndefined(production)) { + AV._config.production = production ? 1 : 0; + } else { + // change to default value + AV._config.production = null; + } +}; + +AV._setServerURLs = function (urls) { + var disableAppRouter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + if (typeof urls !== 'string') { + extend(AV._config.serverURLs, urls); + } else { + AV._config.serverURLs = fillServerURLs(urls); + } + + if (disableAppRouter) { + if (AV._appRouter) { + AV._appRouter.disable(); + } else { + _disableAppRouter = true; + } + } +}; +/** + * Set server URLs for services. + * @function AV.setServerURL + * @since 4.3.0 + * @param {String|ServerURLs} urls URLs for services. if a string was given, it will be applied for all services. + * You can also set them when initializing SDK with `options.serverURL` + */ + + +AV.setServerURL = function (urls) { + return AV._setServerURLs(urls); +}; + +AV.setServerURLs = AV.setServerURL; + +AV.keepErrorRawMessage = function (value) { + AV._sharedConfig.keepErrorRawMessage = value; +}; +/** + * Set a deadline for requests to complete. + * Note that file upload requests are not affected. + * @function AV.setRequestTimeout + * @since 3.6.0 + * @param {number} ms + */ + + +AV.setRequestTimeout = function (ms) { + AV._config.requestTimeout = ms; +}; // backword compatible + + +AV.initialize = AV.init; + +var defineConfig = function defineConfig(property) { + return (0, _defineProperty.default)(AV, property, { + get: function get() { + return AV._config[property]; + }, + set: function set(value) { + AV._config[property] = value; + } + }); +}; + +['applicationId', 'applicationKey', 'masterKey', 'hookKey'].forEach(defineConfig); + +/***/ }), +/* 383 */ +/***/ (function(module, exports, __webpack_require__) { + +var isPrototypeOf = __webpack_require__(20); +var method = __webpack_require__(384); + +var ArrayPrototype = Array.prototype; + +module.exports = function (it) { + var own = it.slice; + return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.slice) ? method : own; +}; + + +/***/ }), +/* 384 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(385); +var entryVirtual = __webpack_require__(38); + +module.exports = entryVirtual('Array').slice; + + +/***/ }), +/* 385 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(0); +var isArray = __webpack_require__(80); +var isConstructor = __webpack_require__(93); +var isObject = __webpack_require__(17); +var toAbsoluteIndex = __webpack_require__(112); +var lengthOfArrayLike = __webpack_require__(42); +var toIndexedObject = __webpack_require__(33); +var createProperty = __webpack_require__(99); +var wellKnownSymbol = __webpack_require__(8); +var arrayMethodHasSpeciesSupport = __webpack_require__(100); +var un$Slice = __webpack_require__(94); + +var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('slice'); + +var SPECIES = wellKnownSymbol('species'); +var $Array = Array; +var max = Math.max; + +// `Array.prototype.slice` method +// https://tc39.es/ecma262/#sec-array.prototype.slice +// fallback for not array-like ES3 strings and DOM objects +$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, { + slice: function slice(start, end) { + var O = toIndexedObject(this); + var length = lengthOfArrayLike(O); + var k = toAbsoluteIndex(start, length); + var fin = toAbsoluteIndex(end === undefined ? length : end, length); + // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible + var Constructor, result, n; + if (isArray(O)) { + Constructor = O.constructor; + // cross-realm fallback + if (isConstructor(Constructor) && (Constructor === $Array || isArray(Constructor.prototype))) { + Constructor = undefined; + } else if (isObject(Constructor)) { + Constructor = Constructor[SPECIES]; + if (Constructor === null) Constructor = undefined; + } + if (Constructor === $Array || Constructor === undefined) { + return un$Slice(O, k, fin); + } + } + result = new (Constructor === undefined ? $Array : Constructor)(max(fin - k, 0)); + for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]); + result.length = n; + return result; + } +}); + + +/***/ }), +/* 386 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(387); +var path = __webpack_require__(13); + +var Object = path.Object; + +var defineProperty = module.exports = function defineProperty(it, key, desc) { + return Object.defineProperty(it, key, desc); +}; + +if (Object.defineProperty.sham) defineProperty.sham = true; + + +/***/ }), +/* 387 */ +/***/ (function(module, exports, __webpack_require__) { + +var $ = __webpack_require__(0); +var DESCRIPTORS = __webpack_require__(19); +var defineProperty = __webpack_require__(32).f; + +// `Object.defineProperty` method +// https://tc39.es/ecma262/#sec-object.defineproperty +// eslint-disable-next-line es-x/no-object-defineproperty -- safe +$({ target: 'Object', stat: true, forced: Object.defineProperty !== defineProperty, sham: !DESCRIPTORS }, { + defineProperty: defineProperty +}); + + +/***/ }), +/* 388 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var ajax = __webpack_require__(103); + +var Cache = __webpack_require__(220); + +function AppRouter(AV) { + var _this = this; + + this.AV = AV; + this.lockedUntil = 0; + Cache.getAsync('serverURLs').then(function (data) { + if (_this.disabled) return; + if (!data) return _this.lock(0); + var serverURLs = data.serverURLs, + lockedUntil = data.lockedUntil; + + _this.AV._setServerURLs(serverURLs, false); + + _this.lockedUntil = lockedUntil; + }).catch(function () { + return _this.lock(0); + }); +} + +AppRouter.prototype.disable = function disable() { + this.disabled = true; +}; + +AppRouter.prototype.lock = function lock(ttl) { + this.lockedUntil = Date.now() + ttl; +}; + +AppRouter.prototype.refresh = function refresh() { + var _this2 = this; + + if (this.disabled) return; + if (Date.now() < this.lockedUntil) return; + this.lock(10); + var url = 'https://app-router.com/2/route'; + return ajax({ + method: 'get', + url: url, + query: { + appId: this.AV.applicationId + } + }).then(function (servers) { + if (_this2.disabled) return; + var ttl = servers.ttl; + if (!ttl) throw new Error('missing ttl'); + ttl = ttl * 1000; + var protocal = 'https://'; + var serverURLs = { + push: protocal + servers.push_server, + stats: protocal + servers.stats_server, + engine: protocal + servers.engine_server, + api: protocal + servers.api_server + }; + + _this2.AV._setServerURLs(serverURLs, false); + + _this2.lock(ttl); + + return Cache.setAsync('serverURLs', { + serverURLs: serverURLs, + lockedUntil: _this2.lockedUntil + }, ttl); + }).catch(function (error) { + // bypass all errors + console.warn("refresh server URLs failed: ".concat(error.message)); + + _this2.lock(600); + }); +}; + +module.exports = AppRouter; + +/***/ }), +/* 389 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(390); + + +/***/ }), +/* 390 */ +/***/ (function(module, exports, __webpack_require__) { + +var parent = __webpack_require__(391); +__webpack_require__(416); +__webpack_require__(417); +__webpack_require__(418); +__webpack_require__(419); +__webpack_require__(420); +// TODO: Remove from `core-js@4` +__webpack_require__(421); +__webpack_require__(422); +__webpack_require__(423); + +module.exports = parent; + + +/***/ }), +/* 391 */ +/***/ (function(module, exports, __webpack_require__) { + +var parent = __webpack_require__(226); + +module.exports = parent; + + +/***/ }), +/* 392 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(210); +__webpack_require__(92); +__webpack_require__(393); +__webpack_require__(400); +__webpack_require__(401); +__webpack_require__(402); +__webpack_require__(403); +__webpack_require__(229); +__webpack_require__(404); +__webpack_require__(405); +__webpack_require__(406); +__webpack_require__(407); +__webpack_require__(408); +__webpack_require__(409); +__webpack_require__(410); +__webpack_require__(411); +__webpack_require__(412); +__webpack_require__(413); +__webpack_require__(414); +__webpack_require__(415); +var path = __webpack_require__(13); + +module.exports = path.Symbol; + + +/***/ }), +/* 393 */ +/***/ (function(module, exports, __webpack_require__) { + +// TODO: Remove this module from `core-js@4` since it's split to modules listed below +__webpack_require__(394); +__webpack_require__(397); +__webpack_require__(398); +__webpack_require__(213); +__webpack_require__(399); + + +/***/ }), +/* 394 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(0); +var global = __webpack_require__(9); +var call = __webpack_require__(11); +var uncurryThis = __webpack_require__(6); +var IS_PURE = __webpack_require__(31); +var DESCRIPTORS = __webpack_require__(19); +var NATIVE_SYMBOL = __webpack_require__(49); +var fails = __webpack_require__(4); +var hasOwn = __webpack_require__(14); +var isPrototypeOf = __webpack_require__(20); +var anObject = __webpack_require__(21); +var toIndexedObject = __webpack_require__(33); +var toPropertyKey = __webpack_require__(82); +var $toString = __webpack_require__(69); +var createPropertyDescriptor = __webpack_require__(41); +var nativeObjectCreate = __webpack_require__(51); +var objectKeys = __webpack_require__(116); +var getOwnPropertyNamesModule = __webpack_require__(111); +var getOwnPropertyNamesExternal = __webpack_require__(395); +var getOwnPropertySymbolsModule = __webpack_require__(115); +var getOwnPropertyDescriptorModule = __webpack_require__(64); +var definePropertyModule = __webpack_require__(32); +var definePropertiesModule = __webpack_require__(147); +var propertyIsEnumerableModule = __webpack_require__(138); +var defineBuiltIn = __webpack_require__(43); +var shared = __webpack_require__(67); +var sharedKey = __webpack_require__(87); +var hiddenKeys = __webpack_require__(89); +var uid = __webpack_require__(109); +var wellKnownSymbol = __webpack_require__(8); +var wrappedWellKnownSymbolModule = __webpack_require__(136); +var defineWellKnownSymbol = __webpack_require__(5); +var defineSymbolToPrimitive = __webpack_require__(227); +var setToStringTag = __webpack_require__(54); +var InternalStateModule = __webpack_require__(91); +var $forEach = __webpack_require__(101).forEach; + +var HIDDEN = sharedKey('hidden'); +var SYMBOL = 'Symbol'; +var PROTOTYPE = 'prototype'; + +var setInternalState = InternalStateModule.set; +var getInternalState = InternalStateModule.getterFor(SYMBOL); + +var ObjectPrototype = Object[PROTOTYPE]; +var $Symbol = global.Symbol; +var SymbolPrototype = $Symbol && $Symbol[PROTOTYPE]; +var TypeError = global.TypeError; +var QObject = global.QObject; +var nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; +var nativeDefineProperty = definePropertyModule.f; +var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f; +var nativePropertyIsEnumerable = propertyIsEnumerableModule.f; +var push = uncurryThis([].push); + +var AllSymbols = shared('symbols'); +var ObjectPrototypeSymbols = shared('op-symbols'); +var WellKnownSymbolsStore = shared('wks'); + +// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 +var USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild; + +// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 +var setSymbolDescriptor = DESCRIPTORS && fails(function () { + return nativeObjectCreate(nativeDefineProperty({}, 'a', { + get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; } + })).a != 7; +}) ? function (O, P, Attributes) { + var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, P); + if (ObjectPrototypeDescriptor) delete ObjectPrototype[P]; + nativeDefineProperty(O, P, Attributes); + if (ObjectPrototypeDescriptor && O !== ObjectPrototype) { + nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor); + } +} : nativeDefineProperty; + +var wrap = function (tag, description) { + var symbol = AllSymbols[tag] = nativeObjectCreate(SymbolPrototype); + setInternalState(symbol, { + type: SYMBOL, + tag: tag, + description: description + }); + if (!DESCRIPTORS) symbol.description = description; + return symbol; +}; + +var $defineProperty = function defineProperty(O, P, Attributes) { + if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes); + anObject(O); + var key = toPropertyKey(P); + anObject(Attributes); + if (hasOwn(AllSymbols, key)) { + if (!Attributes.enumerable) { + if (!hasOwn(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {})); + O[HIDDEN][key] = true; + } else { + if (hasOwn(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false; + Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) }); + } return setSymbolDescriptor(O, key, Attributes); + } return nativeDefineProperty(O, key, Attributes); +}; + +var $defineProperties = function defineProperties(O, Properties) { + anObject(O); + var properties = toIndexedObject(Properties); + var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties)); + $forEach(keys, function (key) { + if (!DESCRIPTORS || call($propertyIsEnumerable, properties, key)) $defineProperty(O, key, properties[key]); + }); + return O; +}; + +var $create = function create(O, Properties) { + return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties); +}; + +var $propertyIsEnumerable = function propertyIsEnumerable(V) { + var P = toPropertyKey(V); + var enumerable = call(nativePropertyIsEnumerable, this, P); + if (this === ObjectPrototype && hasOwn(AllSymbols, P) && !hasOwn(ObjectPrototypeSymbols, P)) return false; + return enumerable || !hasOwn(this, P) || !hasOwn(AllSymbols, P) || hasOwn(this, HIDDEN) && this[HIDDEN][P] + ? enumerable : true; +}; + +var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) { + var it = toIndexedObject(O); + var key = toPropertyKey(P); + if (it === ObjectPrototype && hasOwn(AllSymbols, key) && !hasOwn(ObjectPrototypeSymbols, key)) return; + var descriptor = nativeGetOwnPropertyDescriptor(it, key); + if (descriptor && hasOwn(AllSymbols, key) && !(hasOwn(it, HIDDEN) && it[HIDDEN][key])) { + descriptor.enumerable = true; + } + return descriptor; +}; + +var $getOwnPropertyNames = function getOwnPropertyNames(O) { + var names = nativeGetOwnPropertyNames(toIndexedObject(O)); + var result = []; + $forEach(names, function (key) { + if (!hasOwn(AllSymbols, key) && !hasOwn(hiddenKeys, key)) push(result, key); + }); + return result; +}; + +var $getOwnPropertySymbols = function (O) { + var IS_OBJECT_PROTOTYPE = O === ObjectPrototype; + var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O)); + var result = []; + $forEach(names, function (key) { + if (hasOwn(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwn(ObjectPrototype, key))) { + push(result, AllSymbols[key]); + } + }); + return result; +}; + +// `Symbol` constructor +// https://tc39.es/ecma262/#sec-symbol-constructor +if (!NATIVE_SYMBOL) { + $Symbol = function Symbol() { + if (isPrototypeOf(SymbolPrototype, this)) throw TypeError('Symbol is not a constructor'); + var description = !arguments.length || arguments[0] === undefined ? undefined : $toString(arguments[0]); + var tag = uid(description); + var setter = function (value) { + if (this === ObjectPrototype) call(setter, ObjectPrototypeSymbols, value); + if (hasOwn(this, HIDDEN) && hasOwn(this[HIDDEN], tag)) this[HIDDEN][tag] = false; + setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value)); + }; + if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter }); + return wrap(tag, description); + }; + + SymbolPrototype = $Symbol[PROTOTYPE]; + + defineBuiltIn(SymbolPrototype, 'toString', function toString() { + return getInternalState(this).tag; + }); + + defineBuiltIn($Symbol, 'withoutSetter', function (description) { + return wrap(uid(description), description); + }); + + propertyIsEnumerableModule.f = $propertyIsEnumerable; + definePropertyModule.f = $defineProperty; + definePropertiesModule.f = $defineProperties; + getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor; + getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames; + getOwnPropertySymbolsModule.f = $getOwnPropertySymbols; + + wrappedWellKnownSymbolModule.f = function (name) { + return wrap(wellKnownSymbol(name), name); + }; + + if (DESCRIPTORS) { + // https://github.com/tc39/proposal-Symbol-description + nativeDefineProperty(SymbolPrototype, 'description', { + configurable: true, + get: function description() { + return getInternalState(this).description; + } + }); + if (!IS_PURE) { + defineBuiltIn(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true }); + } + } +} + +$({ global: true, constructor: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, { + Symbol: $Symbol +}); + +$forEach(objectKeys(WellKnownSymbolsStore), function (name) { + defineWellKnownSymbol(name); +}); + +$({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, { + useSetter: function () { USE_SETTER = true; }, + useSimple: function () { USE_SETTER = false; } +}); + +$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, { + // `Object.create` method + // https://tc39.es/ecma262/#sec-object.create + create: $create, + // `Object.defineProperty` method + // https://tc39.es/ecma262/#sec-object.defineproperty + defineProperty: $defineProperty, + // `Object.defineProperties` method + // https://tc39.es/ecma262/#sec-object.defineproperties + defineProperties: $defineProperties, + // `Object.getOwnPropertyDescriptor` method + // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors + getOwnPropertyDescriptor: $getOwnPropertyDescriptor +}); + +$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, { + // `Object.getOwnPropertyNames` method + // https://tc39.es/ecma262/#sec-object.getownpropertynames + getOwnPropertyNames: $getOwnPropertyNames +}); + +// `Symbol.prototype[@@toPrimitive]` method +// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive +defineSymbolToPrimitive(); + +// `Symbol.prototype[@@toStringTag]` property +// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag +setToStringTag($Symbol, SYMBOL); + +hiddenKeys[HIDDEN] = true; + + +/***/ }), +/* 395 */ +/***/ (function(module, exports, __webpack_require__) { + +/* eslint-disable es-x/no-object-getownpropertynames -- safe */ +var classof = __webpack_require__(65); +var toIndexedObject = __webpack_require__(33); +var $getOwnPropertyNames = __webpack_require__(111).f; +var arraySlice = __webpack_require__(396); + +var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames + ? Object.getOwnPropertyNames(window) : []; + +var getWindowNames = function (it) { + try { + return $getOwnPropertyNames(it); + } catch (error) { + return arraySlice(windowNames); + } +}; + +// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window +module.exports.f = function getOwnPropertyNames(it) { + return windowNames && classof(it) == 'Window' + ? getWindowNames(it) + : $getOwnPropertyNames(toIndexedObject(it)); +}; + + +/***/ }), +/* 396 */ +/***/ (function(module, exports, __webpack_require__) { + +var toAbsoluteIndex = __webpack_require__(112); +var lengthOfArrayLike = __webpack_require__(42); +var createProperty = __webpack_require__(99); + +var $Array = Array; +var max = Math.max; + +module.exports = function (O, start, end) { + var length = lengthOfArrayLike(O); + var k = toAbsoluteIndex(start, length); + var fin = toAbsoluteIndex(end === undefined ? length : end, length); + var result = $Array(max(fin - k, 0)); + for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]); + result.length = n; + return result; +}; + + +/***/ }), +/* 397 */ +/***/ (function(module, exports, __webpack_require__) { + +var $ = __webpack_require__(0); +var getBuiltIn = __webpack_require__(16); +var hasOwn = __webpack_require__(14); +var toString = __webpack_require__(69); +var shared = __webpack_require__(67); +var NATIVE_SYMBOL_REGISTRY = __webpack_require__(228); + +var StringToSymbolRegistry = shared('string-to-symbol-registry'); +var SymbolToStringRegistry = shared('symbol-to-string-registry'); + +// `Symbol.for` method +// https://tc39.es/ecma262/#sec-symbol.for +$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, { + 'for': function (key) { + var string = toString(key); + if (hasOwn(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string]; + var symbol = getBuiltIn('Symbol')(string); + StringToSymbolRegistry[string] = symbol; + SymbolToStringRegistry[symbol] = string; + return symbol; + } +}); + + +/***/ }), +/* 398 */ +/***/ (function(module, exports, __webpack_require__) { + +var $ = __webpack_require__(0); +var hasOwn = __webpack_require__(14); +var isSymbol = __webpack_require__(83); +var tryToString = __webpack_require__(66); +var shared = __webpack_require__(67); +var NATIVE_SYMBOL_REGISTRY = __webpack_require__(228); + +var SymbolToStringRegistry = shared('symbol-to-string-registry'); + +// `Symbol.keyFor` method +// https://tc39.es/ecma262/#sec-symbol.keyfor +$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, { + keyFor: function keyFor(sym) { + if (!isSymbol(sym)) throw TypeError(tryToString(sym) + ' is not a symbol'); + if (hasOwn(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym]; + } +}); + + +/***/ }), +/* 399 */ +/***/ (function(module, exports, __webpack_require__) { + +var $ = __webpack_require__(0); +var NATIVE_SYMBOL = __webpack_require__(49); +var fails = __webpack_require__(4); +var getOwnPropertySymbolsModule = __webpack_require__(115); +var toObject = __webpack_require__(35); + +// V8 ~ Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives +// https://bugs.chromium.org/p/v8/issues/detail?id=3443 +var FORCED = !NATIVE_SYMBOL || fails(function () { getOwnPropertySymbolsModule.f(1); }); + +// `Object.getOwnPropertySymbols` method +// https://tc39.es/ecma262/#sec-object.getownpropertysymbols +$({ target: 'Object', stat: true, forced: FORCED }, { + getOwnPropertySymbols: function getOwnPropertySymbols(it) { + var $getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + return $getOwnPropertySymbols ? $getOwnPropertySymbols(toObject(it)) : []; + } +}); + + +/***/ }), +/* 400 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.asyncIterator` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.asynciterator +defineWellKnownSymbol('asyncIterator'); + + +/***/ }), +/* 401 */ +/***/ (function(module, exports) { + +// empty + + +/***/ }), +/* 402 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.hasInstance` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.hasinstance +defineWellKnownSymbol('hasInstance'); + + +/***/ }), +/* 403 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.isConcatSpreadable` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.isconcatspreadable +defineWellKnownSymbol('isConcatSpreadable'); + + +/***/ }), +/* 404 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.match` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.match +defineWellKnownSymbol('match'); + + +/***/ }), +/* 405 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.matchAll` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.matchall +defineWellKnownSymbol('matchAll'); + + +/***/ }), +/* 406 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.replace` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.replace +defineWellKnownSymbol('replace'); + + +/***/ }), +/* 407 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.search` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.search +defineWellKnownSymbol('search'); + + +/***/ }), +/* 408 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.species` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.species +defineWellKnownSymbol('species'); + + +/***/ }), +/* 409 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.split` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.split +defineWellKnownSymbol('split'); + + +/***/ }), +/* 410 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); +var defineSymbolToPrimitive = __webpack_require__(227); + +// `Symbol.toPrimitive` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.toprimitive +defineWellKnownSymbol('toPrimitive'); + +// `Symbol.prototype[@@toPrimitive]` method +// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive +defineSymbolToPrimitive(); + + +/***/ }), +/* 411 */ +/***/ (function(module, exports, __webpack_require__) { + +var getBuiltIn = __webpack_require__(16); +var defineWellKnownSymbol = __webpack_require__(5); +var setToStringTag = __webpack_require__(54); + +// `Symbol.toStringTag` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.tostringtag +defineWellKnownSymbol('toStringTag'); + +// `Symbol.prototype[@@toStringTag]` property +// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag +setToStringTag(getBuiltIn('Symbol'), 'Symbol'); + + +/***/ }), +/* 412 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.unscopables` well-known symbol +// https://tc39.es/ecma262/#sec-symbol.unscopables +defineWellKnownSymbol('unscopables'); + + +/***/ }), +/* 413 */ +/***/ (function(module, exports, __webpack_require__) { + +var global = __webpack_require__(9); +var setToStringTag = __webpack_require__(54); + +// JSON[@@toStringTag] property +// https://tc39.es/ecma262/#sec-json-@@tostringtag +setToStringTag(global.JSON, 'JSON', true); + + +/***/ }), +/* 414 */ +/***/ (function(module, exports) { + +// empty + + +/***/ }), +/* 415 */ +/***/ (function(module, exports) { + +// empty + + +/***/ }), +/* 416 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.asyncDispose` well-known symbol +// https://github.com/tc39/proposal-using-statement +defineWellKnownSymbol('asyncDispose'); + + +/***/ }), +/* 417 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.dispose` well-known symbol +// https://github.com/tc39/proposal-using-statement +defineWellKnownSymbol('dispose'); + + +/***/ }), +/* 418 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.matcher` well-known symbol +// https://github.com/tc39/proposal-pattern-matching +defineWellKnownSymbol('matcher'); + + +/***/ }), +/* 419 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.metadataKey` well-known symbol +// https://github.com/tc39/proposal-decorator-metadata +defineWellKnownSymbol('metadataKey'); + + +/***/ }), +/* 420 */ +/***/ (function(module, exports, __webpack_require__) { + +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.observable` well-known symbol +// https://github.com/tc39/proposal-observable +defineWellKnownSymbol('observable'); + + +/***/ }), +/* 421 */ +/***/ (function(module, exports, __webpack_require__) { + +// TODO: Remove from `core-js@4` +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.metadata` well-known symbol +// https://github.com/tc39/proposal-decorators +defineWellKnownSymbol('metadata'); + + +/***/ }), +/* 422 */ +/***/ (function(module, exports, __webpack_require__) { + +// TODO: remove from `core-js@4` +var defineWellKnownSymbol = __webpack_require__(5); + +// `Symbol.patternMatch` well-known symbol +// https://github.com/tc39/proposal-pattern-matching +defineWellKnownSymbol('patternMatch'); + + +/***/ }), +/* 423 */ +/***/ (function(module, exports, __webpack_require__) { + +// TODO: remove from `core-js@4` +var defineWellKnownSymbol = __webpack_require__(5); + +defineWellKnownSymbol('replaceAll'); + + +/***/ }), +/* 424 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(425); + +/***/ }), +/* 425 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(426); + + +/***/ }), +/* 426 */ +/***/ (function(module, exports, __webpack_require__) { + +var parent = __webpack_require__(427); + +module.exports = parent; + + +/***/ }), +/* 427 */ +/***/ (function(module, exports, __webpack_require__) { + +var parent = __webpack_require__(428); + +module.exports = parent; + + +/***/ }), +/* 428 */ +/***/ (function(module, exports, __webpack_require__) { + +var parent = __webpack_require__(429); +__webpack_require__(73); + +module.exports = parent; + + +/***/ }), +/* 429 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(70); +__webpack_require__(92); +__webpack_require__(95); +__webpack_require__(229); +var WrappedWellKnownSymbolModule = __webpack_require__(136); + +module.exports = WrappedWellKnownSymbolModule.f('iterator'); + + +/***/ }), +/* 430 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(431); + +/***/ }), +/* 431 */ +/***/ (function(module, exports, __webpack_require__) { + +var parent = __webpack_require__(432); + +module.exports = parent; + + +/***/ }), +/* 432 */ +/***/ (function(module, exports, __webpack_require__) { + +var isPrototypeOf = __webpack_require__(20); +var method = __webpack_require__(433); + +var ArrayPrototype = Array.prototype; + +module.exports = function (it) { + var own = it.filter; + return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.filter) ? method : own; +}; + + +/***/ }), +/* 433 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(434); +var entryVirtual = __webpack_require__(38); + +module.exports = entryVirtual('Array').filter; + + +/***/ }), +/* 434 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(0); +var $filter = __webpack_require__(101).filter; +var arrayMethodHasSpeciesSupport = __webpack_require__(100); + +var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter'); + +// `Array.prototype.filter` method +// https://tc39.es/ecma262/#sec-array.prototype.filter +// with adding support of @@species +$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, { + filter: function filter(callbackfn /* , thisArg */) { + return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); + + +/***/ }), +/* 435 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +// Copyright (c) 2015-2017 David M. Lee, II + + +/** + * Local reference to TimeoutError + * @private + */ +var TimeoutError; + +/** + * Rejects a promise with a {@link TimeoutError} if it does not settle within + * the specified timeout. + * + * @param {Promise} promise The promise. + * @param {number} timeoutMillis Number of milliseconds to wait on settling. + * @returns {Promise} Either resolves/rejects with `promise`, or rejects with + * `TimeoutError`, whichever settles first. + */ +var timeout = module.exports.timeout = function(promise, timeoutMillis) { + var error = new TimeoutError(), + timeout; + + return Promise.race([ + promise, + new Promise(function(resolve, reject) { + timeout = setTimeout(function() { + reject(error); + }, timeoutMillis); + }), + ]).then(function(v) { + clearTimeout(timeout); + return v; + }, function(err) { + clearTimeout(timeout); + throw err; + }); +}; + +/** + * Exception indicating that the timeout expired. + */ +TimeoutError = module.exports.TimeoutError = function() { + Error.call(this) + this.stack = Error().stack + this.message = 'Timeout'; +}; + +TimeoutError.prototype = Object.create(Error.prototype); +TimeoutError.prototype.name = "TimeoutError"; + + +/***/ }), +/* 436 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(2); + +var _slice = _interopRequireDefault(__webpack_require__(81)); + +var _keys = _interopRequireDefault(__webpack_require__(48)); + +var _concat = _interopRequireDefault(__webpack_require__(29)); + +var _ = __webpack_require__(1); + +module.exports = function (AV) { + var eventSplitter = /\s+/; + var slice = (0, _slice.default)(Array.prototype); + /** + * @class + * + *AV.Events is a fork of Backbone's Events module, provided for your + * convenience.
+ * + *A module that can be mixed in to any object in order to provide + * it with custom events. You may bind callback functions to an event + * with `on`, or remove these functions with `off`. + * Triggering an event fires all callbacks in the order that `on` was + * called. + * + * @private + * @example + * var object = {}; + * _.extend(object, AV.Events); + * object.on('expand', function(){ alert('expanded'); }); + * object.trigger('expand');
+ * + */ + + AV.Events = { + /** + * Bind one or more space separated events, `events`, to a `callback` + * function. Passing `"all"` will bind the callback to all events fired. + */ + on: function on(events, callback, context) { + var calls, event, node, tail, list; + + if (!callback) { + return this; + } + + events = events.split(eventSplitter); + calls = this._callbacks || (this._callbacks = {}); // Create an immutable callback list, allowing traversal during + // modification. The tail is an empty object that will always be used + // as the next node. + + event = events.shift(); + + while (event) { + list = calls[event]; + node = list ? list.tail : {}; + node.next = tail = {}; + node.context = context; + node.callback = callback; + calls[event] = { + tail: tail, + next: list ? list.next : node + }; + event = events.shift(); + } + + return this; + }, + + /** + * Remove one or many callbacks. If `context` is null, removes all callbacks + * with that function. If `callback` is null, removes all callbacks for the + * event. If `events` is null, removes all bound callbacks for all events. + */ + off: function off(events, callback, context) { + var event, calls, node, tail, cb, ctx; // No events, or removing *all* events. + + if (!(calls = this._callbacks)) { + return; + } + + if (!(events || callback || context)) { + delete this._callbacks; + return this; + } // Loop through the listed events and contexts, splicing them out of the + // linked list of callbacks if appropriate. + + + events = events ? events.split(eventSplitter) : (0, _keys.default)(_).call(_, calls); + event = events.shift(); + + while (event) { + node = calls[event]; + delete calls[event]; + + if (!node || !(callback || context)) { + continue; + } // Create a new list, omitting the indicated callbacks. + + + tail = node.tail; + node = node.next; + + while (node !== tail) { + cb = node.callback; + ctx = node.context; + + if (callback && cb !== callback || context && ctx !== context) { + this.on(event, cb, ctx); + } + + node = node.next; + } + + event = events.shift(); + } + + return this; + }, + + /** + * Trigger one or many events, firing all bound callbacks. Callbacks are + * passed the same arguments as `trigger` is, apart from the event name + * (unless you're listening on `"all"`, which will cause your callback to + * receive the true name of the event as the first argument). + */ + trigger: function trigger(events) { + var event, node, calls, tail, args, all, rest; + + if (!(calls = this._callbacks)) { + return this; + } + + all = calls.all; + events = events.split(eventSplitter); + rest = slice.call(arguments, 1); // For each event, walk through the linked list of callbacks twice, + // first to trigger the event, then to trigger any `"all"` callbacks. + + event = events.shift(); + + while (event) { + node = calls[event]; + + if (node) { + tail = node.tail; + + while ((node = node.next) !== tail) { + node.callback.apply(node.context || this, rest); + } + } + + node = all; + + if (node) { + var _context; + + tail = node.tail; + args = (0, _concat.default)(_context = [event]).call(_context, rest); + + while ((node = node.next) !== tail) { + node.callback.apply(node.context || this, args); + } + } + + event = events.shift(); + } + + return this; + } + }; + /** + * @function + */ + + AV.Events.bind = AV.Events.on; + /** + * @function + */ + + AV.Events.unbind = AV.Events.off; +}; + +/***/ }), +/* 437 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(2); + +var _promise = _interopRequireDefault(__webpack_require__(10)); + +var _ = __webpack_require__(1); +/*global navigator: false */ + + +module.exports = function (AV) { + /** + * Creates a new GeoPoint with any of the following forms:Represents a latitude / longitude point that may be associated + * with a key in a AVObject or used as a reference point for geo queries. + * This allows proximity-based queries on the key.
+ * + *Only one key in a class may contain a GeoPoint.
+ * + *Example:
+ * var point = new AV.GeoPoint(30.0, -20.0); + * var object = new AV.Object("PlaceObject"); + * object.set("location", point); + * object.save();+ */ + AV.GeoPoint = function (arg1, arg2) { + if (_.isArray(arg1)) { + AV.GeoPoint._validate(arg1[0], arg1[1]); + + this.latitude = arg1[0]; + this.longitude = arg1[1]; + } else if (_.isObject(arg1)) { + AV.GeoPoint._validate(arg1.latitude, arg1.longitude); + + this.latitude = arg1.latitude; + this.longitude = arg1.longitude; + } else if (_.isNumber(arg1) && _.isNumber(arg2)) { + AV.GeoPoint._validate(arg1, arg2); + + this.latitude = arg1; + this.longitude = arg2; + } else { + this.latitude = 0; + this.longitude = 0; + } // Add properties so that anyone using Webkit or Mozilla will get an error + // if they try to set values that are out of bounds. + + + var self = this; + + if (this.__defineGetter__ && this.__defineSetter__) { + // Use _latitude and _longitude to actually store the values, and add + // getters and setters for latitude and longitude. + this._latitude = this.latitude; + this._longitude = this.longitude; + + this.__defineGetter__('latitude', function () { + return self._latitude; + }); + + this.__defineGetter__('longitude', function () { + return self._longitude; + }); + + this.__defineSetter__('latitude', function (val) { + AV.GeoPoint._validate(val, self.longitude); + + self._latitude = val; + }); + + this.__defineSetter__('longitude', function (val) { + AV.GeoPoint._validate(self.latitude, val); + + self._longitude = val; + }); + } + }; + /** + * @lends AV.GeoPoint.prototype + * @property {float} latitude North-south portion of the coordinate, in range + * [-90, 90]. Throws an exception if set out of range in a modern browser. + * @property {float} longitude East-west portion of the coordinate, in range + * [-180, 180]. Throws if set out of range in a modern browser. + */ + + /** + * Throws an exception if the given lat-long is out of bounds. + * @private + */ + + + AV.GeoPoint._validate = function (latitude, longitude) { + if (latitude < -90.0) { + throw new Error('AV.GeoPoint latitude ' + latitude + ' < -90.0.'); + } + + if (latitude > 90.0) { + throw new Error('AV.GeoPoint latitude ' + latitude + ' > 90.0.'); + } + + if (longitude < -180.0) { + throw new Error('AV.GeoPoint longitude ' + longitude + ' < -180.0.'); + } + + if (longitude > 180.0) { + throw new Error('AV.GeoPoint longitude ' + longitude + ' > 180.0.'); + } + }; + /** + * Creates a GeoPoint with the user's current location, if available. + * @return {Promise.
An ACL, or Access Control List can be added to any
+ * AV.Object
to restrict access to only a subset of users
+ * of your application.
object.set("foo", "bar")
+ * is an example of a AV.Op.Set. Calling object.unset("foo")
+ * is a AV.Op.Unset. These operations are stored in a AV.Object and
+ * sent to the server as part of object.save()
operations.
+ * Instances of AV.Op should be immutable.
+ *
+ * You should not create subclasses of AV.Op or instantiate AV.Op
+ * directly.
+ */
+ AV.Op = function () {
+ this._initialize.apply(this, arguments);
+ };
+
+ _.extend(AV.Op.prototype,
+ /** @lends AV.Op.prototype */
+ {
+ _initialize: function _initialize() {}
+ });
+
+ _.extend(AV.Op, {
+ /**
+ * To create a new Op, call AV.Op._extend();
+ * @private
+ */
+ _extend: AV._extend,
+ // A map of __op string to decoder function.
+ _opDecoderMap: {},
+
+ /**
+ * Registers a function to convert a json object with an __op field into an
+ * instance of a subclass of AV.Op.
+ * @private
+ */
+ _registerDecoder: function _registerDecoder(opName, decoder) {
+ AV.Op._opDecoderMap[opName] = decoder;
+ },
+
+ /**
+ * Converts a json object into an instance of a subclass of AV.Op.
+ * @private
+ */
+ _decode: function _decode(json) {
+ var decoder = AV.Op._opDecoderMap[json.__op];
+
+ if (decoder) {
+ return decoder(json);
+ } else {
+ return undefined;
+ }
+ }
+ });
+ /*
+ * Add a handler for Batch ops.
+ */
+
+
+ AV.Op._registerDecoder('Batch', function (json) {
+ var op = null;
+
+ AV._arrayEach(json.ops, function (nextOp) {
+ nextOp = AV.Op._decode(nextOp);
+ op = nextOp._mergeWithPrevious(op);
+ });
+
+ return op;
+ });
+ /**
+ * @private
+ * @class
+ * A Set operation indicates that either the field was changed using
+ * AV.Object.set, or it is a mutable container that was detected as being
+ * changed.
+ */
+
+
+ AV.Op.Set = AV.Op._extend(
+ /** @lends AV.Op.Set.prototype */
+ {
+ _initialize: function _initialize(value) {
+ this._value = value;
+ },
+
+ /**
+ * Returns the new value of this field after the set.
+ */
+ value: function value() {
+ return this._value;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return AV._encode(this.value());
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ return this;
+ },
+ _estimate: function _estimate(oldValue) {
+ return this.value();
+ }
+ });
+ /**
+ * A sentinel value that is returned by AV.Op.Unset._estimate to
+ * indicate the field should be deleted. Basically, if you find _UNSET as a
+ * value in your object, you should remove that key.
+ */
+
+ AV.Op._UNSET = {};
+ /**
+ * @private
+ * @class
+ * An Unset operation indicates that this field has been deleted from the
+ * object.
+ */
+
+ AV.Op.Unset = AV.Op._extend(
+ /** @lends AV.Op.Unset.prototype */
+ {
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'Delete'
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ return this;
+ },
+ _estimate: function _estimate(oldValue) {
+ return AV.Op._UNSET;
+ }
+ });
+
+ AV.Op._registerDecoder('Delete', function (json) {
+ return new AV.Op.Unset();
+ });
+ /**
+ * @private
+ * @class
+ * An Increment is an atomic operation where the numeric value for the field
+ * will be increased by a given amount.
+ */
+
+
+ AV.Op.Increment = AV.Op._extend(
+ /** @lends AV.Op.Increment.prototype */
+ {
+ _initialize: function _initialize(amount) {
+ this._amount = amount;
+ },
+
+ /**
+ * Returns the amount to increment by.
+ * @return {Number} the amount to increment by.
+ */
+ amount: function amount() {
+ return this._amount;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'Increment',
+ amount: this._amount
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ return new AV.Op.Set(this.amount());
+ } else if (previous instanceof AV.Op.Set) {
+ return new AV.Op.Set(previous.value() + this.amount());
+ } else if (previous instanceof AV.Op.Increment) {
+ return new AV.Op.Increment(this.amount() + previous.amount());
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue) {
+ if (!oldValue) {
+ return this.amount();
+ }
+
+ return oldValue + this.amount();
+ }
+ });
+
+ AV.Op._registerDecoder('Increment', function (json) {
+ return new AV.Op.Increment(json.amount);
+ });
+ /**
+ * @private
+ * @class
+ * BitAnd is an atomic operation where the given value will be bit and to the
+ * value than is stored in this field.
+ */
+
+
+ AV.Op.BitAnd = AV.Op._extend(
+ /** @lends AV.Op.BitAnd.prototype */
+ {
+ _initialize: function _initialize(value) {
+ this._value = value;
+ },
+ value: function value() {
+ return this._value;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'BitAnd',
+ value: this.value()
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ return new AV.Op.Set(0);
+ } else if (previous instanceof AV.Op.Set) {
+ return new AV.Op.Set(previous.value() & this.value());
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue) {
+ return oldValue & this.value();
+ }
+ });
+
+ AV.Op._registerDecoder('BitAnd', function (json) {
+ return new AV.Op.BitAnd(json.value);
+ });
+ /**
+ * @private
+ * @class
+ * BitOr is an atomic operation where the given value will be bit and to the
+ * value than is stored in this field.
+ */
+
+
+ AV.Op.BitOr = AV.Op._extend(
+ /** @lends AV.Op.BitOr.prototype */
+ {
+ _initialize: function _initialize(value) {
+ this._value = value;
+ },
+ value: function value() {
+ return this._value;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'BitOr',
+ value: this.value()
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ return new AV.Op.Set(this.value());
+ } else if (previous instanceof AV.Op.Set) {
+ return new AV.Op.Set(previous.value() | this.value());
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue) {
+ return oldValue | this.value();
+ }
+ });
+
+ AV.Op._registerDecoder('BitOr', function (json) {
+ return new AV.Op.BitOr(json.value);
+ });
+ /**
+ * @private
+ * @class
+ * BitXor is an atomic operation where the given value will be bit and to the
+ * value than is stored in this field.
+ */
+
+
+ AV.Op.BitXor = AV.Op._extend(
+ /** @lends AV.Op.BitXor.prototype */
+ {
+ _initialize: function _initialize(value) {
+ this._value = value;
+ },
+ value: function value() {
+ return this._value;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'BitXor',
+ value: this.value()
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ return new AV.Op.Set(this.value());
+ } else if (previous instanceof AV.Op.Set) {
+ return new AV.Op.Set(previous.value() ^ this.value());
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue) {
+ return oldValue ^ this.value();
+ }
+ });
+
+ AV.Op._registerDecoder('BitXor', function (json) {
+ return new AV.Op.BitXor(json.value);
+ });
+ /**
+ * @private
+ * @class
+ * Add is an atomic operation where the given objects will be appended to the
+ * array that is stored in this field.
+ */
+
+
+ AV.Op.Add = AV.Op._extend(
+ /** @lends AV.Op.Add.prototype */
+ {
+ _initialize: function _initialize(objects) {
+ this._objects = objects;
+ },
+
+ /**
+ * Returns the objects to be added to the array.
+ * @return {Array} The objects to be added to the array.
+ */
+ objects: function objects() {
+ return this._objects;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'Add',
+ objects: AV._encode(this.objects())
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ return new AV.Op.Set(this.objects());
+ } else if (previous instanceof AV.Op.Set) {
+ return new AV.Op.Set(this._estimate(previous.value()));
+ } else if (previous instanceof AV.Op.Add) {
+ var _context;
+
+ return new AV.Op.Add((0, _concat.default)(_context = previous.objects()).call(_context, this.objects()));
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue) {
+ if (!oldValue) {
+ return _.clone(this.objects());
+ } else {
+ return (0, _concat.default)(oldValue).call(oldValue, this.objects());
+ }
+ }
+ });
+
+ AV.Op._registerDecoder('Add', function (json) {
+ return new AV.Op.Add(AV._decode(json.objects));
+ });
+ /**
+ * @private
+ * @class
+ * AddUnique is an atomic operation where the given items will be appended to
+ * the array that is stored in this field only if they were not already
+ * present in the array.
+ */
+
+
+ AV.Op.AddUnique = AV.Op._extend(
+ /** @lends AV.Op.AddUnique.prototype */
+ {
+ _initialize: function _initialize(objects) {
+ this._objects = _.uniq(objects);
+ },
+
+ /**
+ * Returns the objects to be added to the array.
+ * @return {Array} The objects to be added to the array.
+ */
+ objects: function objects() {
+ return this._objects;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'AddUnique',
+ objects: AV._encode(this.objects())
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ return new AV.Op.Set(this.objects());
+ } else if (previous instanceof AV.Op.Set) {
+ return new AV.Op.Set(this._estimate(previous.value()));
+ } else if (previous instanceof AV.Op.AddUnique) {
+ return new AV.Op.AddUnique(this._estimate(previous.objects()));
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue) {
+ if (!oldValue) {
+ return _.clone(this.objects());
+ } else {
+ // We can't just take the _.uniq(_.union(...)) of oldValue and
+ // this.objects, because the uniqueness may not apply to oldValue
+ // (especially if the oldValue was set via .set())
+ var newValue = _.clone(oldValue);
+
+ AV._arrayEach(this.objects(), function (obj) {
+ if (obj instanceof AV.Object && obj.id) {
+ var matchingObj = (0, _find.default)(_).call(_, newValue, function (anObj) {
+ return anObj instanceof AV.Object && anObj.id === obj.id;
+ });
+
+ if (!matchingObj) {
+ newValue.push(obj);
+ } else {
+ var index = (0, _indexOf.default)(_).call(_, newValue, matchingObj);
+ newValue[index] = obj;
+ }
+ } else if (!_.contains(newValue, obj)) {
+ newValue.push(obj);
+ }
+ });
+
+ return newValue;
+ }
+ }
+ });
+
+ AV.Op._registerDecoder('AddUnique', function (json) {
+ return new AV.Op.AddUnique(AV._decode(json.objects));
+ });
+ /**
+ * @private
+ * @class
+ * Remove is an atomic operation where the given objects will be removed from
+ * the array that is stored in this field.
+ */
+
+
+ AV.Op.Remove = AV.Op._extend(
+ /** @lends AV.Op.Remove.prototype */
+ {
+ _initialize: function _initialize(objects) {
+ this._objects = _.uniq(objects);
+ },
+
+ /**
+ * Returns the objects to be removed from the array.
+ * @return {Array} The objects to be removed from the array.
+ */
+ objects: function objects() {
+ return this._objects;
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ return {
+ __op: 'Remove',
+ objects: AV._encode(this.objects())
+ };
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ return previous;
+ } else if (previous instanceof AV.Op.Set) {
+ return new AV.Op.Set(this._estimate(previous.value()));
+ } else if (previous instanceof AV.Op.Remove) {
+ return new AV.Op.Remove(_.union(previous.objects(), this.objects()));
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue) {
+ if (!oldValue) {
+ return [];
+ } else {
+ var newValue = _.difference(oldValue, this.objects()); // If there are saved AV Objects being removed, also remove them.
+
+
+ AV._arrayEach(this.objects(), function (obj) {
+ if (obj instanceof AV.Object && obj.id) {
+ newValue = _.reject(newValue, function (other) {
+ return other instanceof AV.Object && other.id === obj.id;
+ });
+ }
+ });
+
+ return newValue;
+ }
+ }
+ });
+
+ AV.Op._registerDecoder('Remove', function (json) {
+ return new AV.Op.Remove(AV._decode(json.objects));
+ });
+ /**
+ * @private
+ * @class
+ * A Relation operation indicates that the field is an instance of
+ * AV.Relation, and objects are being added to, or removed from, that
+ * relation.
+ */
+
+
+ AV.Op.Relation = AV.Op._extend(
+ /** @lends AV.Op.Relation.prototype */
+ {
+ _initialize: function _initialize(adds, removes) {
+ this._targetClassName = null;
+ var self = this;
+
+ var pointerToId = function pointerToId(object) {
+ if (object instanceof AV.Object) {
+ if (!object.id) {
+ throw new Error("You can't add an unsaved AV.Object to a relation.");
+ }
+
+ if (!self._targetClassName) {
+ self._targetClassName = object.className;
+ }
+
+ if (self._targetClassName !== object.className) {
+ throw new Error('Tried to create a AV.Relation with 2 different types: ' + self._targetClassName + ' and ' + object.className + '.');
+ }
+
+ return object.id;
+ }
+
+ return object;
+ };
+
+ this.relationsToAdd = _.uniq((0, _map.default)(_).call(_, adds, pointerToId));
+ this.relationsToRemove = _.uniq((0, _map.default)(_).call(_, removes, pointerToId));
+ },
+
+ /**
+ * Returns an array of unfetched AV.Object that are being added to the
+ * relation.
+ * @return {Array}
+ */
+ added: function added() {
+ var self = this;
+ return (0, _map.default)(_).call(_, this.relationsToAdd, function (objectId) {
+ var object = AV.Object._create(self._targetClassName);
+
+ object.id = objectId;
+ return object;
+ });
+ },
+
+ /**
+ * Returns an array of unfetched AV.Object that are being removed from
+ * the relation.
+ * @return {Array}
+ */
+ removed: function removed() {
+ var self = this;
+ return (0, _map.default)(_).call(_, this.relationsToRemove, function (objectId) {
+ var object = AV.Object._create(self._targetClassName);
+
+ object.id = objectId;
+ return object;
+ });
+ },
+
+ /**
+ * Returns a JSON version of the operation suitable for sending to AV.
+ * @return {Object}
+ */
+ toJSON: function toJSON() {
+ var adds = null;
+ var removes = null;
+ var self = this;
+
+ var idToPointer = function idToPointer(id) {
+ return {
+ __type: 'Pointer',
+ className: self._targetClassName,
+ objectId: id
+ };
+ };
+
+ var pointers = null;
+
+ if (this.relationsToAdd.length > 0) {
+ pointers = (0, _map.default)(_).call(_, this.relationsToAdd, idToPointer);
+ adds = {
+ __op: 'AddRelation',
+ objects: pointers
+ };
+ }
+
+ if (this.relationsToRemove.length > 0) {
+ pointers = (0, _map.default)(_).call(_, this.relationsToRemove, idToPointer);
+ removes = {
+ __op: 'RemoveRelation',
+ objects: pointers
+ };
+ }
+
+ if (adds && removes) {
+ return {
+ __op: 'Batch',
+ ops: [adds, removes]
+ };
+ }
+
+ return adds || removes || {};
+ },
+ _mergeWithPrevious: function _mergeWithPrevious(previous) {
+ if (!previous) {
+ return this;
+ } else if (previous instanceof AV.Op.Unset) {
+ throw new Error("You can't modify a relation after deleting it.");
+ } else if (previous instanceof AV.Op.Relation) {
+ if (previous._targetClassName && previous._targetClassName !== this._targetClassName) {
+ throw new Error('Related object must be of class ' + previous._targetClassName + ', but ' + this._targetClassName + ' was passed in.');
+ }
+
+ var newAdd = _.union(_.difference(previous.relationsToAdd, this.relationsToRemove), this.relationsToAdd);
+
+ var newRemove = _.union(_.difference(previous.relationsToRemove, this.relationsToAdd), this.relationsToRemove);
+
+ var newRelation = new AV.Op.Relation(newAdd, newRemove);
+ newRelation._targetClassName = this._targetClassName;
+ return newRelation;
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ },
+ _estimate: function _estimate(oldValue, object, key) {
+ if (!oldValue) {
+ var relation = new AV.Relation(object, key);
+ relation.targetClassName = this._targetClassName;
+ } else if (oldValue instanceof AV.Relation) {
+ if (this._targetClassName) {
+ if (oldValue.targetClassName) {
+ if (oldValue.targetClassName !== this._targetClassName) {
+ throw new Error('Related object must be a ' + oldValue.targetClassName + ', but a ' + this._targetClassName + ' was passed in.');
+ }
+ } else {
+ oldValue.targetClassName = this._targetClassName;
+ }
+ }
+
+ return oldValue;
+ } else {
+ throw new Error('Op is invalid after previous op.');
+ }
+ }
+ });
+
+ AV.Op._registerDecoder('AddRelation', function (json) {
+ return new AV.Op.Relation(AV._decode(json.objects), []);
+ });
+
+ AV.Op._registerDecoder('RemoveRelation', function (json) {
+ return new AV.Op.Relation([], AV._decode(json.objects));
+ });
+};
+
+/***/ }),
+/* 440 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(441);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 441 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var isPrototypeOf = __webpack_require__(20);
+var method = __webpack_require__(442);
+
+var ArrayPrototype = Array.prototype;
+
+module.exports = function (it) {
+ var own = it.find;
+ return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.find) ? method : own;
+};
+
+
+/***/ }),
+/* 442 */
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__(443);
+var entryVirtual = __webpack_require__(38);
+
+module.exports = entryVirtual('Array').find;
+
+
+/***/ }),
+/* 443 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+var $ = __webpack_require__(0);
+var $find = __webpack_require__(101).find;
+var addToUnscopables = __webpack_require__(152);
+
+var FIND = 'find';
+var SKIPS_HOLES = true;
+
+// Shouldn't skip holes
+if (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });
+
+// `Array.prototype.find` method
+// https://tc39.es/ecma262/#sec-array.prototype.find
+$({ target: 'Array', proto: true, forced: SKIPS_HOLES }, {
+ find: function find(callbackfn /* , that = undefined */) {
+ return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
+ }
+});
+
+// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
+addToUnscopables(FIND);
+
+
+/***/ }),
+/* 444 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _ = __webpack_require__(1);
+
+module.exports = function (AV) {
+ /**
+ * Creates a new Relation for the given parent object and key. This
+ * constructor should rarely be used directly, but rather created by
+ * {@link AV.Object#relation}.
+ * @param {AV.Object} parent The parent of this relation.
+ * @param {String} key The key for this relation on the parent.
+ * @see AV.Object#relation
+ * @class
+ *
+ * + * A class that is used to access all of the children of a many-to-many + * relationship. Each instance of AV.Relation is associated with a + * particular parent object and key. + *
+ */ + AV.Relation = function (parent, key) { + if (!_.isString(key)) { + throw new TypeError('key must be a string'); + } + + this.parent = parent; + this.key = key; + this.targetClassName = null; + }; + /** + * Creates a query that can be used to query the parent objects in this relation. + * @param {String} parentClass The parent class or name. + * @param {String} relationKey The relation field key in parent. + * @param {AV.Object} child The child object. + * @return {AV.Query} + */ + + + AV.Relation.reverseQuery = function (parentClass, relationKey, child) { + var query = new AV.Query(parentClass); + query.equalTo(relationKey, child._toPointer()); + return query; + }; + + _.extend(AV.Relation.prototype, + /** @lends AV.Relation.prototype */ + { + /** + * Makes sure that this relation has the right parent and key. + * @private + */ + _ensureParentAndKey: function _ensureParentAndKey(parent, key) { + this.parent = this.parent || parent; + this.key = this.key || key; + + if (this.parent !== parent) { + throw new Error('Internal Error. Relation retrieved from two different Objects.'); + } + + if (this.key !== key) { + throw new Error('Internal Error. Relation retrieved from two different keys.'); + } + }, + + /** + * Adds a AV.Object or an array of AV.Objects to the relation. + * @param {AV.Object|AV.Object[]} objects The item or items to add. + */ + add: function add(objects) { + if (!_.isArray(objects)) { + objects = [objects]; + } + + var change = new AV.Op.Relation(objects, []); + this.parent.set(this.key, change); + this.targetClassName = change._targetClassName; + }, + + /** + * Removes a AV.Object or an array of AV.Objects from this relation. + * @param {AV.Object|AV.Object[]} objects The item or items to remove. + */ + remove: function remove(objects) { + if (!_.isArray(objects)) { + objects = [objects]; + } + + var change = new AV.Op.Relation([], objects); + this.parent.set(this.key, change); + this.targetClassName = change._targetClassName; + }, + + /** + * Returns a JSON version of the object suitable for saving to disk. + * @return {Object} + */ + toJSON: function toJSON() { + return { + __type: 'Relation', + className: this.targetClassName + }; + }, + + /** + * Returns a AV.Query that is limited to objects in this + * relation. + * @return {AV.Query} + */ + query: function query() { + var targetClass; + var query; + + if (!this.targetClassName) { + targetClass = AV.Object._getSubclass(this.parent.className); + query = new AV.Query(targetClass); + query._defaultParams.redirectClassNameForKey = this.key; + } else { + targetClass = AV.Object._getSubclass(this.targetClassName); + query = new AV.Query(targetClass); + } + + query._addCondition('$relatedTo', 'object', this.parent._toPointer()); + + query._addCondition('$relatedTo', 'key', this.key); + + return query; + } + }); +}; + +/***/ }), +/* 445 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(2); + +var _promise = _interopRequireDefault(__webpack_require__(10)); + +var _ = __webpack_require__(1); + +var cos = __webpack_require__(446); + +var qiniu = __webpack_require__(447); + +var s3 = __webpack_require__(495); + +var AVError = __webpack_require__(40); + +var _require = __webpack_require__(25), + request = _require.request, + AVRequest = _require._request; + +var _require2 = __webpack_require__(28), + tap = _require2.tap, + transformFetchOptions = _require2.transformFetchOptions; + +var debug = __webpack_require__(60)('leancloud:file'); + +var parseBase64 = __webpack_require__(499); + +module.exports = function (AV) { + // port from browserify path module + // since react-native packager won't shim node modules. + var extname = function extname(path) { + if (!_.isString(path)) return ''; + return path.match(/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/)[4]; + }; + + var b64Digit = function b64Digit(number) { + if (number < 26) { + return String.fromCharCode(65 + number); + } + + if (number < 52) { + return String.fromCharCode(97 + (number - 26)); + } + + if (number < 62) { + return String.fromCharCode(48 + (number - 52)); + } + + if (number === 62) { + return '+'; + } + + if (number === 63) { + return '/'; + } + + throw new Error('Tried to encode large digit ' + number + ' in base64.'); + }; + + var encodeBase64 = function encodeBase64(array) { + var chunks = []; + chunks.length = Math.ceil(array.length / 3); + + _.times(chunks.length, function (i) { + var b1 = array[i * 3]; + var b2 = array[i * 3 + 1] || 0; + var b3 = array[i * 3 + 2] || 0; + var has2 = i * 3 + 1 < array.length; + var has3 = i * 3 + 2 < array.length; + chunks[i] = [b64Digit(b1 >> 2 & 0x3f), b64Digit(b1 << 4 & 0x30 | b2 >> 4 & 0x0f), has2 ? b64Digit(b2 << 2 & 0x3c | b3 >> 6 & 0x03) : '=', has3 ? b64Digit(b3 & 0x3f) : '='].join(''); + }); + + return chunks.join(''); + }; + /** + * An AV.File is a local representation of a file that is saved to the AV + * cloud. + * @param name {String} The file's name. This will change to a unique value + * once the file has finished saving. + * @param data {Array} The data for the file, as either: + * 1. an Array of byte value Numbers, or + * 2. an Object like { base64: "..." } with a base64-encoded String. + * 3. a Blob(File) selected with a file upload control in a browser. + * 4. an Object like { blob: {uri: "..."} } that mimics Blob + * in some non-browser environments such as React Native. + * 5. a Buffer in Node.js runtime. + * 6. a Stream in Node.js runtime. + * + * For example:+ * var fileUploadControl = $("#profilePhotoFileUpload")[0]; + * if (fileUploadControl.files.length > 0) { + * var file = fileUploadControl.files[0]; + * var name = "photo.jpg"; + * var file = new AV.File(name, file); + * file.save().then(function() { + * // The file has been saved to AV. + * }, function(error) { + * // The file either could not be read, or could not be saved to AV. + * }); + * }+ * + * @class + * @param [mimeType] {String} Content-Type header to use for the file. If + * this is omitted, the content type will be inferred from the name's + * extension. + */ + + + AV.File = function (name, data, mimeType) { + this.attributes = { + name: name, + url: '', + metaData: {}, + // 用来存储转换后要上传的 base64 String + base64: '' + }; + + if (_.isString(data)) { + throw new TypeError('Creating an AV.File from a String is not yet supported.'); + } + + if (_.isArray(data)) { + this.attributes.metaData.size = data.length; + data = { + base64: encodeBase64(data) + }; + } + + this._extName = ''; + this._data = data; + this._uploadHeaders = {}; + + if (data && data.blob && typeof data.blob.uri === 'string') { + this._extName = extname(data.blob.uri); + } + + if (typeof Blob !== 'undefined' && data instanceof Blob) { + if (data.size) { + this.attributes.metaData.size = data.size; + } + + if (data.name) { + this._extName = extname(data.name); + } + } + + var owner; + + if (data && data.owner) { + owner = data.owner; + } else if (!AV._config.disableCurrentUser) { + try { + owner = AV.User.current(); + } catch (error) { + if ('SYNC_API_NOT_AVAILABLE' !== error.code) { + throw error; + } + } + } + + this.attributes.metaData.owner = owner ? owner.id : 'unknown'; + this.set('mime_type', mimeType); + }; + /** + * Creates a fresh AV.File object with exists url for saving to AVOS Cloud. + * @param {String} name the file name + * @param {String} url the file url. + * @param {Object} [metaData] the file metadata object. + * @param {String} [type] Content-Type header to use for the file. If + * this is omitted, the content type will be inferred from the name's + * extension. + * @return {AV.File} the file object + */ + + + AV.File.withURL = function (name, url, metaData, type) { + if (!name || !url) { + throw new Error('Please provide file name and url'); + } + + var file = new AV.File(name, null, type); //copy metaData properties to file. + + if (metaData) { + for (var prop in metaData) { + if (!file.attributes.metaData[prop]) file.attributes.metaData[prop] = metaData[prop]; + } + } + + file.attributes.url = url; //Mark the file is from external source. + + file.attributes.metaData.__source = 'external'; + file.attributes.metaData.size = 0; + return file; + }; + /** + * Creates a file object with exists objectId. + * @param {String} objectId The objectId string + * @return {AV.File} the file object + */ + + + AV.File.createWithoutData = function (objectId) { + if (!objectId) { + throw new TypeError('The objectId must be provided'); + } + + var file = new AV.File(); + file.id = objectId; + return file; + }; + /** + * Request file censor. + * @since 4.13.0 + * @param {String} objectId + * @return {Promise.
Returns the file's metadata JSON object if no arguments is given.Returns the + * metadata value if a key is given.Set metadata value if key and value are both given.
+ *+ * var metadata = file.metaData(); //Get metadata JSON object. + * var size = file.metaData('size'); // Get the size metadata value. + * file.metaData('format', 'jpeg'); //set metadata attribute and value. + *+ * @return {Object} The file's metadata JSON object. + * @param {String} attr an optional metadata key. + * @param {Object} value an optional metadata value. + **/ + metaData: function metaData(attr, value) { + if (attr && value) { + this.attributes.metaData[attr] = value; + return this; + } else if (attr && !value) { + return this.attributes.metaData[attr]; + } else { + return this.attributes.metaData; + } + }, + + /** + * 如果文件是图片,获取图片的缩略图URL。可以传入宽度、高度、质量、格式等参数。 + * @return {String} 缩略图URL + * @param {Number} width 宽度,单位:像素 + * @param {Number} heigth 高度,单位:像素 + * @param {Number} quality 质量,1-100的数字,默认100 + * @param {Number} scaleToFit 是否将图片自适应大小。默认为true。 + * @param {String} fmt 格式,默认为png,也可以为jpeg,gif等格式。 + */ + thumbnailURL: function thumbnailURL(width, height) { + var quality = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100; + var scaleToFit = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var fmt = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'png'; + var url = this.attributes.url; + + if (!url) { + throw new Error('Invalid url.'); + } + + if (!width || !height || width <= 0 || height <= 0) { + throw new Error('Invalid width or height value.'); + } + + if (quality <= 0 || quality > 100) { + throw new Error('Invalid quality value.'); + } + + var mode = scaleToFit ? 2 : 1; + return url + '?imageView/' + mode + '/w/' + width + '/h/' + height + '/q/' + quality + '/format/' + fmt; + }, + + /** + * Returns the file's size. + * @return {Number} The file's size in bytes. + **/ + size: function size() { + return this.metaData().size; + }, + + /** + * Returns the file's owner. + * @return {String} The file's owner id. + */ + ownerId: function ownerId() { + return this.metaData().owner; + }, + + /** + * Destroy the file. + * @param {AuthOptions} options + * @return {Promise} A promise that is fulfilled when the destroy + * completes. + */ + destroy: function destroy(options) { + if (!this.id) { + return _promise.default.reject(new Error('The file id does not eixst.')); + } + + var request = AVRequest('files', null, this.id, 'DELETE', null, options); + return request; + }, + + /** + * Request Qiniu upload token + * @param {string} type + * @return {Promise} Resolved with the response + * @private + */ + _fileToken: function _fileToken(type, authOptions) { + var name = this.attributes.name; + var extName = extname(name); + + if (!extName && this._extName) { + name += this._extName; + extName = this._extName; + } + + var data = { + name: name, + keep_file_name: authOptions.keepFileName, + key: authOptions.key, + ACL: this._acl, + mime_type: type, + metaData: this.attributes.metaData + }; + return AVRequest('fileTokens', null, null, 'POST', data, authOptions); + }, + + /** + * @callback UploadProgressCallback + * @param {XMLHttpRequestProgressEvent} event - The progress event with 'loaded' and 'total' attributes + */ + + /** + * Saves the file to the AV cloud. + * @param {AuthOptions} [options] AuthOptions plus: + * @param {UploadProgressCallback} [options.onprogress] 文件上传进度,在 Node.js 中无效,回调参数说明详见 {@link UploadProgressCallback}。 + * @param {boolean} [options.keepFileName = false] 保留下载文件的文件名。 + * @param {string} [options.key] 指定文件的 key。设置该选项需要使用 masterKey + * @return {Promise} Promise that is resolved when the save finishes. + */ + save: function save() { + var _this3 = this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (this.id) { + throw new Error('File is already saved.'); + } + + if (!this._previousSave) { + if (this._data) { + var mimeType = this.get('mime_type'); + this._previousSave = this._fileToken(mimeType, options).then(function (uploadInfo) { + if (uploadInfo.mime_type) { + mimeType = uploadInfo.mime_type; + + _this3.set('mime_type', mimeType); + } + + _this3._token = uploadInfo.token; + return _promise.default.resolve().then(function () { + var data = _this3._data; + + if (data && data.base64) { + return parseBase64(data.base64, mimeType); + } + + if (data && data.blob) { + if (!data.blob.type && mimeType) { + data.blob.type = mimeType; + } + + if (!data.blob.name) { + data.blob.name = _this3.get('name'); + } + + return data.blob; + } + + if (typeof Blob !== 'undefined' && data instanceof Blob) { + return data; + } + + throw new TypeError('malformed file data'); + }).then(function (data) { + var _options = _.extend({}, options); // filter out download progress events + + + if (options.onprogress) { + _options.onprogress = function (event) { + if (event.direction === 'download') return; + return options.onprogress(event); + }; + } + + switch (uploadInfo.provider) { + case 's3': + return s3(uploadInfo, data, _this3, _options); + + case 'qcloud': + return cos(uploadInfo, data, _this3, _options); + + case 'qiniu': + default: + return qiniu(uploadInfo, data, _this3, _options); + } + }).then(tap(function () { + return _this3._callback(true); + }), function (error) { + _this3._callback(false); + + throw error; + }); + }); + } else if (this.attributes.url && this.attributes.metaData.__source === 'external') { + // external link file. + var data = { + name: this.attributes.name, + ACL: this._acl, + metaData: this.attributes.metaData, + mime_type: this.mimeType, + url: this.attributes.url + }; + this._previousSave = AVRequest('files', null, null, 'post', data, options).then(function (response) { + _this3.id = response.objectId; + return _this3; + }); + } + } + + return this._previousSave; + }, + _callback: function _callback(success) { + AVRequest('fileCallback', null, null, 'post', { + token: this._token, + result: success + }).catch(debug); + delete this._token; + delete this._data; + }, + + /** + * fetch the file from server. If the server's representation of the + * model differs from its current attributes, they will be overriden, + * @param {Object} fetchOptions Optional options to set 'keys', + * 'include' and 'includeACL' option. + * @param {AuthOptions} options + * @return {Promise} A promise that is fulfilled when the fetch + * completes. + */ + fetch: function fetch(fetchOptions, options) { + if (!this.id) { + throw new Error('Cannot fetch unsaved file'); + } + + var request = AVRequest('files', null, this.id, 'GET', transformFetchOptions(fetchOptions), options); + return request.then(this._finishFetch.bind(this)); + }, + _finishFetch: function _finishFetch(response) { + var value = AV.Object.prototype.parse(response); + value.attributes = { + name: value.name, + url: value.url, + mime_type: value.mime_type, + bucket: value.bucket + }; + value.attributes.metaData = value.metaData || {}; + value.id = value.objectId; // clean + + delete value.objectId; + delete value.metaData; + delete value.url; + delete value.name; + delete value.mime_type; + delete value.bucket; + + _.extend(this, value); + + return this; + }, + + /** + * Request file censor + * @since 4.13.0 + * @return {Promise.
You won't normally call this method directly. It is recommended that
+ * you use a subclass of AV.Object
instead, created by calling
+ * extend
.
However, if you don't want to use a subclass, or aren't sure which + * subclass is appropriate, you can use this form:
+ * var object = new AV.Object("ClassName"); + *+ * That is basically equivalent to:
+ * var MyClass = AV.Object.extend("ClassName"); + * var object = new MyClass(); + *+ * + * @param {Object} attributes The initial set of data to store in the object. + * @param {Object} options A set of Backbone-like options for creating the + * object. The only option currently supported is "collection". + * @see AV.Object.extend + * + * @class + * + *
The fundamental unit of AV data, which implements the Backbone Model + * interface.
+ */ + AV.Object = function (attributes, options) { + // Allow new AV.Object("ClassName") as a shortcut to _create. + if (_.isString(attributes)) { + return AV.Object._create.apply(this, arguments); + } + + attributes = attributes || {}; + + if (options && options.parse) { + attributes = this.parse(attributes); + attributes = this._mergeMagicFields(attributes); + } + + var defaults = getValue(this, 'defaults'); + + if (defaults) { + attributes = _.extend({}, defaults, attributes); + } + + if (options && options.collection) { + this.collection = options.collection; + } + + this._serverData = {}; // The last known data for this object from cloud. + + this._opSetQueue = [{}]; // List of sets of changes to the data. + + this._flags = {}; + this.attributes = {}; // The best estimate of this's current data. + + this._hashedJSON = {}; // Hash of values of containers at last save. + + this._escapedAttributes = {}; + this.cid = _.uniqueId('c'); + this.changed = {}; + this._silent = {}; + this._pending = {}; + this.set(attributes, { + silent: true + }); + this.changed = {}; + this._silent = {}; + this._pending = {}; + this._hasData = true; + this._previousAttributes = _.clone(this.attributes); + this.initialize.apply(this, arguments); + }; + /** + * @lends AV.Object.prototype + * @property {String} id The objectId of the AV Object. + */ + + /** + * Saves the given list of AV.Object. + * If any error is encountered, stops and calls the error handler. + * + * @example + * AV.Object.saveAll([object1, object2, ...]).then(function(list) { + * // All the objects were saved. + * }, function(error) { + * // An error occurred while saving one of the objects. + * }); + * + * @param {Array} list A list ofAV.Object
.
+ */
+
+
+ AV.Object.saveAll = function (list, options) {
+ return AV.Object._deepSaveAsync(list, null, options);
+ };
+ /**
+ * Fetch the given list of AV.Object.
+ *
+ * @param {AV.Object[]} objects A list of AV.Object
+ * @param {AuthOptions} options
+ * @return {Promise.AV.Object
, updated
+ */
+
+
+ AV.Object.fetchAll = function (objects, options) {
+ return _promise.default.resolve().then(function () {
+ return _request('batch', null, null, 'POST', {
+ requests: (0, _map.default)(_).call(_, objects, function (object) {
+ var _context;
+
+ if (!object.className) throw new Error('object must have className to fetch');
+ if (!object.id) throw new Error('object must have id to fetch');
+ if (object.dirty()) throw new Error('object is modified but not saved');
+ return {
+ method: 'GET',
+ path: (0, _concat.default)(_context = "/1.1/classes/".concat(object.className, "/")).call(_context, object.id)
+ };
+ })
+ }, options);
+ }).then(function (response) {
+ var results = (0, _map.default)(_).call(_, objects, function (object, i) {
+ if (response[i].success) {
+ var fetchedAttrs = object.parse(response[i].success);
+
+ object._cleanupUnsetKeys(fetchedAttrs);
+
+ object._finishFetch(fetchedAttrs);
+
+ return object;
+ }
+
+ if (response[i].success === null) {
+ return new AVError(AVError.OBJECT_NOT_FOUND, 'Object not found.');
+ }
+
+ return new AVError(response[i].error.code, response[i].error.error);
+ });
+ return handleBatchResults(results);
+ });
+ }; // Attach all inheritable methods to the AV.Object prototype.
+
+
+ _.extend(AV.Object.prototype, AV.Events,
+ /** @lends AV.Object.prototype */
+ {
+ _fetchWhenSave: false,
+
+ /**
+ * Initialize is an empty function by default. Override it with your own
+ * initialization logic.
+ */
+ initialize: function initialize() {},
+
+ /**
+ * Set whether to enable fetchWhenSave option when updating object.
+ * When set true, SDK would fetch the latest object after saving.
+ * Default is false.
+ *
+ * @deprecated use AV.Object#save with options.fetchWhenSave instead
+ * @param {boolean} enable true to enable fetchWhenSave option.
+ */
+ fetchWhenSave: function fetchWhenSave(enable) {
+ console.warn('AV.Object#fetchWhenSave is deprecated, use AV.Object#save with options.fetchWhenSave instead.');
+
+ if (!_.isBoolean(enable)) {
+ throw new Error('Expect boolean value for fetchWhenSave');
+ }
+
+ this._fetchWhenSave = enable;
+ },
+
+ /**
+ * Returns the object's objectId.
+ * @return {String} the objectId.
+ */
+ getObjectId: function getObjectId() {
+ return this.id;
+ },
+
+ /**
+ * Returns the object's createdAt attribute.
+ * @return {Date}
+ */
+ getCreatedAt: function getCreatedAt() {
+ return this.createdAt;
+ },
+
+ /**
+ * Returns the object's updatedAt attribute.
+ * @return {Date}
+ */
+ getUpdatedAt: function getUpdatedAt() {
+ return this.updatedAt;
+ },
+
+ /**
+ * Returns a JSON version of the object.
+ * @return {Object}
+ */
+ toJSON: function toJSON(key, holder) {
+ var seenObjects = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
+ return this._toFullJSON(seenObjects, false);
+ },
+
+ /**
+ * Returns a JSON version of the object with meta data.
+ * Inverse to {@link AV.parseJSON}
+ * @since 3.0.0
+ * @return {Object}
+ */
+ toFullJSON: function toFullJSON() {
+ var seenObjects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
+ return this._toFullJSON(seenObjects);
+ },
+ _toFullJSON: function _toFullJSON(seenObjects) {
+ var _this = this;
+
+ var full = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
+
+ var json = _.clone(this.attributes);
+
+ if (_.isArray(seenObjects)) {
+ var newSeenObjects = (0, _concat.default)(seenObjects).call(seenObjects, this);
+ }
+
+ AV._objectEach(json, function (val, key) {
+ json[key] = AV._encode(val, newSeenObjects, undefined, full);
+ });
+
+ AV._objectEach(this._operations, function (val, key) {
+ json[key] = val;
+ });
+
+ if (_.has(this, 'id')) {
+ json.objectId = this.id;
+ }
+
+ ['createdAt', 'updatedAt'].forEach(function (key) {
+ if (_.has(_this, key)) {
+ var val = _this[key];
+ json[key] = _.isDate(val) ? val.toJSON() : val;
+ }
+ });
+
+ if (full) {
+ json.__type = 'Object';
+ if (_.isArray(seenObjects) && seenObjects.length) json.__type = 'Pointer';
+ json.className = this.className;
+ }
+
+ return json;
+ },
+
+ /**
+ * Updates _hashedJSON to reflect the current state of this object.
+ * Adds any changed hash values to the set of pending changes.
+ * @private
+ */
+ _refreshCache: function _refreshCache() {
+ var self = this;
+
+ if (self._refreshingCache) {
+ return;
+ }
+
+ self._refreshingCache = true;
+
+ AV._objectEach(this.attributes, function (value, key) {
+ if (value instanceof AV.Object) {
+ value._refreshCache();
+ } else if (_.isObject(value)) {
+ if (self._resetCacheForKey(key)) {
+ self.set(key, new AV.Op.Set(value), {
+ silent: true
+ });
+ }
+ }
+ });
+
+ delete self._refreshingCache;
+ },
+
+ /**
+ * Returns true if this object has been modified since its last
+ * save/refresh. If an attribute is specified, it returns true only if that
+ * particular attribute has been modified since the last save/refresh.
+ * @param {String} attr An attribute name (optional).
+ * @return {Boolean}
+ */
+ dirty: function dirty(attr) {
+ this._refreshCache();
+
+ var currentChanges = _.last(this._opSetQueue);
+
+ if (attr) {
+ return currentChanges[attr] ? true : false;
+ }
+
+ if (!this.id) {
+ return true;
+ }
+
+ if ((0, _keys2.default)(_).call(_, currentChanges).length > 0) {
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * Returns the keys of the modified attribute since its last save/refresh.
+ * @return {String[]}
+ */
+ dirtyKeys: function dirtyKeys() {
+ this._refreshCache();
+
+ var currentChanges = _.last(this._opSetQueue);
+
+ return (0, _keys2.default)(_).call(_, currentChanges);
+ },
+
+ /**
+ * Gets a Pointer referencing this Object.
+ * @private
+ */
+ _toPointer: function _toPointer() {
+ // if (!this.id) {
+ // throw new Error("Can't serialize an unsaved AV.Object");
+ // }
+ return {
+ __type: 'Pointer',
+ className: this.className,
+ objectId: this.id
+ };
+ },
+
+ /**
+ * Gets the value of an attribute.
+ * @param {String} attr The string name of an attribute.
+ */
+ get: function get(attr) {
+ switch (attr) {
+ case 'objectId':
+ return this.id;
+
+ case 'createdAt':
+ case 'updatedAt':
+ return this[attr];
+
+ default:
+ return this.attributes[attr];
+ }
+ },
+
+ /**
+ * Gets a relation on the given class for the attribute.
+ * @param {String} attr The attribute to get the relation for.
+ * @return {AV.Relation}
+ */
+ relation: function relation(attr) {
+ var value = this.get(attr);
+
+ if (value) {
+ if (!(value instanceof AV.Relation)) {
+ throw new Error('Called relation() on non-relation field ' + attr);
+ }
+
+ value._ensureParentAndKey(this, attr);
+
+ return value;
+ } else {
+ return new AV.Relation(this, attr);
+ }
+ },
+
+ /**
+ * Gets the HTML-escaped value of an attribute.
+ */
+ escape: function escape(attr) {
+ var html = this._escapedAttributes[attr];
+
+ if (html) {
+ return html;
+ }
+
+ var val = this.attributes[attr];
+ var escaped;
+
+ if (isNullOrUndefined(val)) {
+ escaped = '';
+ } else {
+ escaped = _.escape(val.toString());
+ }
+
+ this._escapedAttributes[attr] = escaped;
+ return escaped;
+ },
+
+ /**
+ * Returns true
if the attribute contains a value that is not
+ * null or undefined.
+ * @param {String} attr The string name of the attribute.
+ * @return {Boolean}
+ */
+ has: function has(attr) {
+ return !isNullOrUndefined(this.attributes[attr]);
+ },
+
+ /**
+ * Pulls "special" fields like objectId, createdAt, etc. out of attrs
+ * and puts them on "this" directly. Removes them from attrs.
+ * @param attrs - A dictionary with the data for this AV.Object.
+ * @private
+ */
+ _mergeMagicFields: function _mergeMagicFields(attrs) {
+ // Check for changes of magic fields.
+ var model = this;
+ var specialFields = ['objectId', 'createdAt', 'updatedAt'];
+
+ AV._arrayEach(specialFields, function (attr) {
+ if (attrs[attr]) {
+ if (attr === 'objectId') {
+ model.id = attrs[attr];
+ } else if ((attr === 'createdAt' || attr === 'updatedAt') && !_.isDate(attrs[attr])) {
+ model[attr] = AV._parseDate(attrs[attr]);
+ } else {
+ model[attr] = attrs[attr];
+ }
+
+ delete attrs[attr];
+ }
+ });
+
+ return attrs;
+ },
+
+ /**
+ * Returns the json to be sent to the server.
+ * @private
+ */
+ _startSave: function _startSave() {
+ this._opSetQueue.push({});
+ },
+
+ /**
+ * Called when a save fails because of an error. Any changes that were part
+ * of the save need to be merged with changes made after the save. This
+ * might throw an exception is you do conflicting operations. For example,
+ * if you do:
+ * object.set("foo", "bar");
+ * object.set("invalid field name", "baz");
+ * object.save();
+ * object.increment("foo");
+ * then this will throw when the save fails and the client tries to merge
+ * "bar" with the +1.
+ * @private
+ */
+ _cancelSave: function _cancelSave() {
+ var failedChanges = _.first(this._opSetQueue);
+
+ this._opSetQueue = _.rest(this._opSetQueue);
+
+ var nextChanges = _.first(this._opSetQueue);
+
+ AV._objectEach(failedChanges, function (op, key) {
+ var op1 = failedChanges[key];
+ var op2 = nextChanges[key];
+
+ if (op1 && op2) {
+ nextChanges[key] = op2._mergeWithPrevious(op1);
+ } else if (op1) {
+ nextChanges[key] = op1;
+ }
+ });
+
+ this._saving = this._saving - 1;
+ },
+
+ /**
+ * Called when a save completes successfully. This merges the changes that
+ * were saved into the known server data, and overrides it with any data
+ * sent directly from the server.
+ * @private
+ */
+ _finishSave: function _finishSave(serverData) {
+ var _context2;
+
+ // Grab a copy of any object referenced by this object. These instances
+ // may have already been fetched, and we don't want to lose their data.
+ // Note that doing it like this means we will unify separate copies of the
+ // same object, but that's a risk we have to take.
+ var fetchedObjects = {};
+
+ AV._traverse(this.attributes, function (object) {
+ if (object instanceof AV.Object && object.id && object._hasData) {
+ fetchedObjects[object.id] = object;
+ }
+ });
+
+ var savedChanges = _.first(this._opSetQueue);
+
+ this._opSetQueue = _.rest(this._opSetQueue);
+
+ this._applyOpSet(savedChanges, this._serverData);
+
+ this._mergeMagicFields(serverData);
+
+ var self = this;
+
+ AV._objectEach(serverData, function (value, key) {
+ self._serverData[key] = AV._decode(value, key); // Look for any objects that might have become unfetched and fix them
+ // by replacing their values with the previously observed values.
+
+ var fetched = AV._traverse(self._serverData[key], function (object) {
+ if (object instanceof AV.Object && fetchedObjects[object.id]) {
+ return fetchedObjects[object.id];
+ }
+ });
+
+ if (fetched) {
+ self._serverData[key] = fetched;
+ }
+ });
+
+ this._rebuildAllEstimatedData();
+
+ var opSetQueue = (0, _map.default)(_context2 = this._opSetQueue).call(_context2, _.clone);
+
+ this._refreshCache();
+
+ this._opSetQueue = opSetQueue;
+ this._saving = this._saving - 1;
+ },
+
+ /**
+ * Called when a fetch or login is complete to set the known server data to
+ * the given object.
+ * @private
+ */
+ _finishFetch: function _finishFetch(serverData, hasData) {
+ // Clear out any changes the user might have made previously.
+ this._opSetQueue = [{}]; // Bring in all the new server data.
+
+ this._mergeMagicFields(serverData);
+
+ var self = this;
+
+ AV._objectEach(serverData, function (value, key) {
+ self._serverData[key] = AV._decode(value, key);
+ }); // Refresh the attributes.
+
+
+ this._rebuildAllEstimatedData(); // Clear out the cache of mutable containers.
+
+
+ this._refreshCache();
+
+ this._opSetQueue = [{}];
+ this._hasData = hasData;
+ },
+
+ /**
+ * Applies the set of AV.Op in opSet to the object target.
+ * @private
+ */
+ _applyOpSet: function _applyOpSet(opSet, target) {
+ var self = this;
+
+ AV._objectEach(opSet, function (change, key) {
+ var _findValue = findValue(target, key),
+ _findValue2 = (0, _slicedToArray2.default)(_findValue, 3),
+ value = _findValue2[0],
+ actualTarget = _findValue2[1],
+ actualKey = _findValue2[2];
+
+ setValue(target, key, change._estimate(value, self, key));
+
+ if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {
+ delete actualTarget[actualKey];
+ }
+ });
+ },
+
+ /**
+ * Replaces the cached value for key with the current value.
+ * Returns true if the new value is different than the old value.
+ * @private
+ */
+ _resetCacheForKey: function _resetCacheForKey(key) {
+ var value = this.attributes[key];
+
+ if (_.isObject(value) && !(value instanceof AV.Object) && !(value instanceof AV.File)) {
+ var json = (0, _stringify.default)(recursiveToPointer(value));
+
+ if (this._hashedJSON[key] !== json) {
+ var wasSet = !!this._hashedJSON[key];
+ this._hashedJSON[key] = json;
+ return wasSet;
+ }
+ }
+
+ return false;
+ },
+
+ /**
+ * Populates attributes[key] by starting with the last known data from the
+ * server, and applying all of the local changes that have been made to that
+ * key since then.
+ * @private
+ */
+ _rebuildEstimatedDataForKey: function _rebuildEstimatedDataForKey(key) {
+ var self = this;
+ delete this.attributes[key];
+
+ if (this._serverData[key]) {
+ this.attributes[key] = this._serverData[key];
+ }
+
+ AV._arrayEach(this._opSetQueue, function (opSet) {
+ var op = opSet[key];
+
+ if (op) {
+ var _findValue3 = findValue(self.attributes, key),
+ _findValue4 = (0, _slicedToArray2.default)(_findValue3, 4),
+ value = _findValue4[0],
+ actualTarget = _findValue4[1],
+ actualKey = _findValue4[2],
+ firstKey = _findValue4[3];
+
+ setValue(self.attributes, key, op._estimate(value, self, key));
+
+ if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {
+ delete actualTarget[actualKey];
+ }
+
+ self._resetCacheForKey(firstKey);
+ }
+ });
+ },
+
+ /**
+ * Populates attributes by starting with the last known data from the
+ * server, and applying all of the local changes that have been made since
+ * then.
+ * @private
+ */
+ _rebuildAllEstimatedData: function _rebuildAllEstimatedData() {
+ var self = this;
+
+ var previousAttributes = _.clone(this.attributes);
+
+ this.attributes = _.clone(this._serverData);
+
+ AV._arrayEach(this._opSetQueue, function (opSet) {
+ self._applyOpSet(opSet, self.attributes);
+
+ AV._objectEach(opSet, function (op, key) {
+ self._resetCacheForKey(key);
+ });
+ }); // Trigger change events for anything that changed because of the fetch.
+
+
+ AV._objectEach(previousAttributes, function (oldValue, key) {
+ if (self.attributes[key] !== oldValue) {
+ self.trigger('change:' + key, self, self.attributes[key], {});
+ }
+ });
+
+ AV._objectEach(this.attributes, function (newValue, key) {
+ if (!_.has(previousAttributes, key)) {
+ self.trigger('change:' + key, self, newValue, {});
+ }
+ });
+ },
+
+ /**
+ * Sets a hash of model attributes on the object, firing
+ * "change"
unless you choose to silence it.
+ *
+ * You can call it with an object containing keys and values, or with one + * key and value. For example:
+ * + * @example + * gameTurn.set({ + * player: player1, + * diceRoll: 2 + * }); + * + * game.set("currentPlayer", player2); + * + * game.set("finished", true); + * + * @param {String} key The key to set. + * @param {Any} value The value to give it. + * @param {Object} [options] + * @param {Boolean} [options.silent] + * @return {AV.Object} self if succeeded, throws if the value is not valid. + * @see AV.Object#validate + */ + set: function set(key, value, options) { + var attrs; + + if (_.isObject(key) || isNullOrUndefined(key)) { + attrs = _.mapObject(key, function (v, k) { + checkReservedKey(k); + return AV._decode(v, k); + }); + options = value; + } else { + attrs = {}; + checkReservedKey(key); + attrs[key] = AV._decode(value, key); + } // Extract attributes and options. + + + options = options || {}; + + if (!attrs) { + return this; + } + + if (attrs instanceof AV.Object) { + attrs = attrs.attributes; + } // If the unset option is used, every attribute should be a Unset. + + + if (options.unset) { + AV._objectEach(attrs, function (unused_value, key) { + attrs[key] = new AV.Op.Unset(); + }); + } // Apply all the attributes to get the estimated values. + + + var dataToValidate = _.clone(attrs); + + var self = this; + + AV._objectEach(dataToValidate, function (value, key) { + if (value instanceof AV.Op) { + dataToValidate[key] = value._estimate(self.attributes[key], self, key); + + if (dataToValidate[key] === AV.Op._UNSET) { + delete dataToValidate[key]; + } + } + }); // Run validation. + + + this._validate(attrs, options); + + options.changes = {}; + var escaped = this._escapedAttributes; // Update attributes. + + AV._arrayEach((0, _keys2.default)(_).call(_, attrs), function (attr) { + var val = attrs[attr]; // If this is a relation object we need to set the parent correctly, + // since the location where it was parsed does not have access to + // this object. + + if (val instanceof AV.Relation) { + val.parent = self; + } + + if (!(val instanceof AV.Op)) { + val = new AV.Op.Set(val); + } // See if this change will actually have any effect. + + + var isRealChange = true; + + if (val instanceof AV.Op.Set && _.isEqual(self.attributes[attr], val.value)) { + isRealChange = false; + } + + if (isRealChange) { + delete escaped[attr]; + + if (options.silent) { + self._silent[attr] = true; + } else { + options.changes[attr] = true; + } + } + + var currentChanges = _.last(self._opSetQueue); + + currentChanges[attr] = val._mergeWithPrevious(currentChanges[attr]); + + self._rebuildEstimatedDataForKey(attr); + + if (isRealChange) { + self.changed[attr] = self.attributes[attr]; + + if (!options.silent) { + self._pending[attr] = true; + } + } else { + delete self.changed[attr]; + delete self._pending[attr]; + } + }); + + if (!options.silent) { + this.change(options); + } + + return this; + }, + + /** + * Remove an attribute from the model, firing"change"
unless
+ * you choose to silence it. This is a noop if the attribute doesn't
+ * exist.
+ * @param key {String} The key.
+ */
+ unset: function unset(attr, options) {
+ options = options || {};
+ options.unset = true;
+ return this.set(attr, null, options);
+ },
+
+ /**
+ * Atomically increments the value of the given attribute the next time the
+ * object is saved. If no amount is specified, 1 is used by default.
+ *
+ * @param key {String} The key.
+ * @param amount {Number} The amount to increment by.
+ */
+ increment: function increment(attr, amount) {
+ if (_.isUndefined(amount) || _.isNull(amount)) {
+ amount = 1;
+ }
+
+ return this.set(attr, new AV.Op.Increment(amount));
+ },
+
+ /**
+ * Atomically add an object to the end of the array associated with a given
+ * key.
+ * @param key {String} The key.
+ * @param item {} The item to add.
+ */
+ add: function add(attr, item) {
+ return this.set(attr, new AV.Op.Add(ensureArray(item)));
+ },
+
+ /**
+ * Atomically add an object to the array associated with a given key, only
+ * if it is not already present in the array. The position of the insert is
+ * not guaranteed.
+ *
+ * @param key {String} The key.
+ * @param item {} The object to add.
+ */
+ addUnique: function addUnique(attr, item) {
+ return this.set(attr, new AV.Op.AddUnique(ensureArray(item)));
+ },
+
+ /**
+ * Atomically remove all instances of an object from the array associated
+ * with a given key.
+ *
+ * @param key {String} The key.
+ * @param item {} The object to remove.
+ */
+ remove: function remove(attr, item) {
+ return this.set(attr, new AV.Op.Remove(ensureArray(item)));
+ },
+
+ /**
+ * Atomically apply a "bit and" operation on the value associated with a
+ * given key.
+ *
+ * @param key {String} The key.
+ * @param value {Number} The value to apply.
+ */
+ bitAnd: function bitAnd(attr, value) {
+ return this.set(attr, new AV.Op.BitAnd(value));
+ },
+
+ /**
+ * Atomically apply a "bit or" operation on the value associated with a
+ * given key.
+ *
+ * @param key {String} The key.
+ * @param value {Number} The value to apply.
+ */
+ bitOr: function bitOr(attr, value) {
+ return this.set(attr, new AV.Op.BitOr(value));
+ },
+
+ /**
+ * Atomically apply a "bit xor" operation on the value associated with a
+ * given key.
+ *
+ * @param key {String} The key.
+ * @param value {Number} The value to apply.
+ */
+ bitXor: function bitXor(attr, value) {
+ return this.set(attr, new AV.Op.BitXor(value));
+ },
+
+ /**
+ * Returns an instance of a subclass of AV.Op describing what kind of
+ * modification has been performed on this field since the last time it was
+ * saved. For example, after calling object.increment("x"), calling
+ * object.op("x") would return an instance of AV.Op.Increment.
+ *
+ * @param key {String} The key.
+ * @returns {AV.Op} The operation, or undefined if none.
+ */
+ op: function op(attr) {
+ return _.last(this._opSetQueue)[attr];
+ },
+
+ /**
+ * Clear all attributes on the model, firing "change"
unless
+ * you choose to silence it.
+ */
+ clear: function clear(options) {
+ options = options || {};
+ options.unset = true;
+
+ var keysToClear = _.extend(this.attributes, this._operations);
+
+ return this.set(keysToClear, options);
+ },
+
+ /**
+ * Clears any (or specific) changes to the model made since the last save.
+ * @param {string|string[]} [keys] specify keys to revert.
+ */
+ revert: function revert(keys) {
+ var lastOp = _.last(this._opSetQueue);
+
+ var _keys = ensureArray(keys || (0, _keys2.default)(_).call(_, lastOp));
+
+ _keys.forEach(function (key) {
+ delete lastOp[key];
+ });
+
+ this._rebuildAllEstimatedData();
+
+ return this;
+ },
+
+ /**
+ * Returns a JSON-encoded set of operations to be sent with the next save
+ * request.
+ * @private
+ */
+ _getSaveJSON: function _getSaveJSON() {
+ var json = _.clone(_.first(this._opSetQueue));
+
+ AV._objectEach(json, function (op, key) {
+ json[key] = op.toJSON();
+ });
+
+ return json;
+ },
+
+ /**
+ * Returns true if this object can be serialized for saving.
+ * @private
+ */
+ _canBeSerialized: function _canBeSerialized() {
+ return AV.Object._canBeSerializedAsValue(this.attributes);
+ },
+
+ /**
+ * Fetch the model from the server. If the server's representation of the
+ * model differs from its current attributes, they will be overriden,
+ * triggering a "change"
event.
+ * @param {Object} fetchOptions Optional options to set 'keys',
+ * 'include' and 'includeACL' option.
+ * @param {AuthOptions} options
+ * @return {Promise} A promise that is fulfilled when the fetch
+ * completes.
+ */
+ fetch: function fetch() {
+ var fetchOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+ var options = arguments.length > 1 ? arguments[1] : undefined;
+
+ if (!this.id) {
+ throw new Error('Cannot fetch unsaved object');
+ }
+
+ var self = this;
+
+ var request = _request('classes', this.className, this.id, 'GET', transformFetchOptions(fetchOptions), options);
+
+ return request.then(function (response) {
+ var fetchedAttrs = self.parse(response);
+
+ self._cleanupUnsetKeys(fetchedAttrs, (0, _keys2.default)(fetchOptions) ? ensureArray((0, _keys2.default)(fetchOptions)).join(',').split(',') : undefined);
+
+ self._finishFetch(fetchedAttrs, true);
+
+ return self;
+ });
+ },
+ _cleanupUnsetKeys: function _cleanupUnsetKeys(fetchedAttrs) {
+ var _this2 = this;
+
+ var fetchedKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (0, _keys2.default)(_).call(_, this._serverData);
+
+ _.forEach(fetchedKeys, function (key) {
+ if (fetchedAttrs[key] === undefined) delete _this2._serverData[key];
+ });
+ },
+
+ /**
+ * Set a hash of model attributes, and save the model to the server.
+ * updatedAt will be updated when the request returns.
+ * You can either call it as:+ * object.save();+ * or
+ * object.save(null, options);+ * or
+ * object.save(attrs, options);+ * or
+ * object.save(key, value, options);+ * + * @example + * gameTurn.save({ + * player: "Jake Cutter", + * diceRoll: 2 + * }).then(function(gameTurnAgain) { + * // The save was successful. + * }, function(error) { + * // The save failed. Error is an instance of AVError. + * }); + * + * @param {AuthOptions} options AuthOptions plus: + * @param {Boolean} options.fetchWhenSave fetch and update object after save succeeded + * @param {AV.Query} options.query Save object only when it matches the query + * @return {Promise} A promise that is fulfilled when the save + * completes. + * @see AVError + */ + save: function save(arg1, arg2, arg3) { + var attrs, current, options; + + if (_.isObject(arg1) || isNullOrUndefined(arg1)) { + attrs = arg1; + options = arg2; + } else { + attrs = {}; + attrs[arg1] = arg2; + options = arg3; + } + + options = _.clone(options) || {}; + + if (options.wait) { + current = _.clone(this.attributes); + } + + var setOptions = _.clone(options) || {}; + + if (setOptions.wait) { + setOptions.silent = true; + } + + if (attrs) { + this.set(attrs, setOptions); + } + + var model = this; + var unsavedChildren = []; + var unsavedFiles = []; + + AV.Object._findUnsavedChildren(model, unsavedChildren, unsavedFiles); + + if (unsavedChildren.length + unsavedFiles.length > 1) { + return AV.Object._deepSaveAsync(this, model, options); + } + + this._startSave(); + + this._saving = (this._saving || 0) + 1; + this._allPreviousSaves = this._allPreviousSaves || _promise.default.resolve(); + this._allPreviousSaves = this._allPreviousSaves.catch(function (e) {}).then(function () { + var method = model.id ? 'PUT' : 'POST'; + + var json = model._getSaveJSON(); + + var query = {}; + + if (model._fetchWhenSave || options.fetchWhenSave) { + query['new'] = 'true'; + } // user login option + + + if (options._failOnNotExist) { + query.failOnNotExist = 'true'; + } + + if (options.query) { + var queryParams; + + if (typeof options.query._getParams === 'function') { + queryParams = options.query._getParams(); + + if (queryParams) { + query.where = queryParams.where; + } + } + + if (!query.where) { + var error = new Error('options.query is not an AV.Query'); + throw error; + } + } + + _.extend(json, model._flags); + + var route = 'classes'; + var className = model.className; + + if (model.className === '_User' && !model.id) { + // Special-case user sign-up. + route = 'users'; + className = null; + } //hook makeRequest in options. + + + var makeRequest = options._makeRequest || _request; + var requestPromise = makeRequest(route, className, model.id, method, json, options, query); + requestPromise = requestPromise.then(function (resp) { + var serverAttrs = model.parse(resp); + + if (options.wait) { + serverAttrs = _.extend(attrs || {}, serverAttrs); + } + + model._finishSave(serverAttrs); + + if (options.wait) { + model.set(current, setOptions); + } + + return model; + }, function (error) { + model._cancelSave(); + + throw error; + }); + return requestPromise; + }); + return this._allPreviousSaves; + }, + + /** + * Destroy this model on the server if it was already persisted. + * Optimistically removes the model from its collection, if it has one. + * @param {AuthOptions} options AuthOptions plus: + * @param {Boolean} [options.wait] wait for the server to respond + * before removal. + * + * @return {Promise} A promise that is fulfilled when the destroy + * completes. + */ + destroy: function destroy(options) { + options = options || {}; + var model = this; + + var triggerDestroy = function triggerDestroy() { + model.trigger('destroy', model, model.collection, options); + }; + + if (!this.id) { + return triggerDestroy(); + } + + if (!options.wait) { + triggerDestroy(); + } + + var request = _request('classes', this.className, this.id, 'DELETE', this._flags, options); + + return request.then(function () { + if (options.wait) { + triggerDestroy(); + } + + return model; + }); + }, + + /** + * Converts a response into the hash of attributes to be set on the model. + * @ignore + */ + parse: function parse(resp) { + var output = _.clone(resp); + + ['createdAt', 'updatedAt'].forEach(function (key) { + if (output[key]) { + output[key] = AV._parseDate(output[key]); + } + }); + + if (output.createdAt && !output.updatedAt) { + output.updatedAt = output.createdAt; + } + + return output; + }, + + /** + * Creates a new model with identical attributes to this one. + * @return {AV.Object} + */ + clone: function clone() { + return new this.constructor(this.attributes); + }, + + /** + * Returns true if this object has never been saved to AV. + * @return {Boolean} + */ + isNew: function isNew() { + return !this.id; + }, + + /** + * Call this method to manually fire a `"change"` event for this model and + * a `"change:attribute"` event for each changed attribute. + * Calling this will cause all objects observing the model to update. + */ + change: function change(options) { + options = options || {}; + var changing = this._changing; + this._changing = true; // Silent changes become pending changes. + + var self = this; + + AV._objectEach(this._silent, function (attr) { + self._pending[attr] = true; + }); // Silent changes are triggered. + + + var changes = _.extend({}, options.changes, this._silent); + + this._silent = {}; + + AV._objectEach(changes, function (unused_value, attr) { + self.trigger('change:' + attr, self, self.get(attr), options); + }); + + if (changing) { + return this; + } // This is to get around lint not letting us make a function in a loop. + + + var deleteChanged = function deleteChanged(value, attr) { + if (!self._pending[attr] && !self._silent[attr]) { + delete self.changed[attr]; + } + }; // Continue firing `"change"` events while there are pending changes. + + + while (!_.isEmpty(this._pending)) { + this._pending = {}; + this.trigger('change', this, options); // Pending and silent changes still remain. + + AV._objectEach(this.changed, deleteChanged); + + self._previousAttributes = _.clone(this.attributes); + } + + this._changing = false; + return this; + }, + + /** + * Gets the previous value of an attribute, recorded at the time the last + *
"change"
event was fired.
+ * @param {String} attr Name of the attribute to get.
+ */
+ previous: function previous(attr) {
+ if (!arguments.length || !this._previousAttributes) {
+ return null;
+ }
+
+ return this._previousAttributes[attr];
+ },
+
+ /**
+ * Gets all of the attributes of the model at the time of the previous
+ * "change"
event.
+ * @return {Object}
+ */
+ previousAttributes: function previousAttributes() {
+ return _.clone(this._previousAttributes);
+ },
+
+ /**
+ * Checks if the model is currently in a valid state. It's only possible to
+ * get into an *invalid* state if you're using silent changes.
+ * @return {Boolean}
+ */
+ isValid: function isValid() {
+ try {
+ this.validate(this.attributes);
+ } catch (error) {
+ return false;
+ }
+
+ return true;
+ },
+
+ /**
+ * You should not call this function directly unless you subclass
+ * AV.Object
, in which case you can override this method
+ * to provide additional validation on set
and
+ * save
. Your implementation should throw an Error if
+ * the attrs is invalid
+ *
+ * @param {Object} attrs The current data to validate.
+ * @see AV.Object#set
+ */
+ validate: function validate(attrs) {
+ if (_.has(attrs, 'ACL') && !(attrs.ACL instanceof AV.ACL)) {
+ throw new AVError(AVError.OTHER_CAUSE, 'ACL must be a AV.ACL.');
+ }
+ },
+
+ /**
+ * Run validation against a set of incoming attributes, returning `true`
+ * if all is well. If a specific `error` callback has been passed,
+ * call that instead of firing the general `"error"` event.
+ * @private
+ */
+ _validate: function _validate(attrs, options) {
+ if (options.silent || !this.validate) {
+ return;
+ }
+
+ attrs = _.extend({}, this.attributes, attrs);
+ this.validate(attrs);
+ },
+
+ /**
+ * Returns the ACL for this object.
+ * @returns {AV.ACL} An instance of AV.ACL.
+ * @see AV.Object#get
+ */
+ getACL: function getACL() {
+ return this.get('ACL');
+ },
+
+ /**
+ * Sets the ACL to be used for this object.
+ * @param {AV.ACL} acl An instance of AV.ACL.
+ * @param {Object} options Optional Backbone-like options object to be
+ * passed in to set.
+ * @return {AV.Object} self
+ * @see AV.Object#set
+ */
+ setACL: function setACL(acl, options) {
+ return this.set('ACL', acl, options);
+ },
+ disableBeforeHook: function disableBeforeHook() {
+ this.ignoreHook('beforeSave');
+ this.ignoreHook('beforeUpdate');
+ this.ignoreHook('beforeDelete');
+ },
+ disableAfterHook: function disableAfterHook() {
+ this.ignoreHook('afterSave');
+ this.ignoreHook('afterUpdate');
+ this.ignoreHook('afterDelete');
+ },
+ ignoreHook: function ignoreHook(hookName) {
+ if (!_.contains(['beforeSave', 'afterSave', 'beforeUpdate', 'afterUpdate', 'beforeDelete', 'afterDelete'], hookName)) {
+ throw new Error('Unsupported hookName: ' + hookName);
+ }
+
+ if (!AV.hookKey) {
+ throw new Error('ignoreHook required hookKey');
+ }
+
+ if (!this._flags.__ignore_hooks) {
+ this._flags.__ignore_hooks = [];
+ }
+
+ this._flags.__ignore_hooks.push(hookName);
+ }
+ });
+ /**
+ * Creates an instance of a subclass of AV.Object for the give classname
+ * and id.
+ * @param {String|Function} class the className or a subclass of AV.Object.
+ * @param {String} id The object id of this model.
+ * @return {AV.Object} A new subclass instance of AV.Object.
+ */
+
+
+ AV.Object.createWithoutData = function (klass, id, hasData) {
+ var _klass;
+
+ if (_.isString(klass)) {
+ _klass = AV.Object._getSubclass(klass);
+ } else if (klass.prototype && klass.prototype instanceof AV.Object) {
+ _klass = klass;
+ } else {
+ throw new Error('class must be a string or a subclass of AV.Object.');
+ }
+
+ if (!id) {
+ throw new TypeError('The objectId must be provided');
+ }
+
+ var object = new _klass();
+ object.id = id;
+ object._hasData = hasData;
+ return object;
+ };
+ /**
+ * Delete objects in batch.
+ * @param {AV.Object[]} objects The AV.Object
array to be deleted.
+ * @param {AuthOptions} options
+ * @return {Promise} A promise that is fulfilled when the save
+ * completes.
+ */
+
+
+ AV.Object.destroyAll = function (objects) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+
+ if (!objects || objects.length === 0) {
+ return _promise.default.resolve();
+ }
+
+ var objectsByClassNameAndFlags = _.groupBy(objects, function (object) {
+ return (0, _stringify.default)({
+ className: object.className,
+ flags: object._flags
+ });
+ });
+
+ var body = {
+ requests: (0, _map.default)(_).call(_, objectsByClassNameAndFlags, function (objects) {
+ var _context3;
+
+ var ids = (0, _map.default)(_).call(_, objects, 'id').join(',');
+ return {
+ method: 'DELETE',
+ path: (0, _concat.default)(_context3 = "/1.1/classes/".concat(objects[0].className, "/")).call(_context3, ids),
+ body: objects[0]._flags
+ };
+ })
+ };
+ return _request('batch', null, null, 'POST', body, options).then(function (response) {
+ var firstError = (0, _find.default)(_).call(_, response, function (result) {
+ return !result.success;
+ });
+ if (firstError) throw new AVError(firstError.error.code, firstError.error.error);
+ return undefined;
+ });
+ };
+ /**
+ * Returns the appropriate subclass for making new instances of the given
+ * className string.
+ * @private
+ */
+
+
+ AV.Object._getSubclass = function (className) {
+ if (!_.isString(className)) {
+ throw new Error('AV.Object._getSubclass requires a string argument.');
+ }
+
+ var ObjectClass = AV.Object._classMap[className];
+
+ if (!ObjectClass) {
+ ObjectClass = AV.Object.extend(className);
+ AV.Object._classMap[className] = ObjectClass;
+ }
+
+ return ObjectClass;
+ };
+ /**
+ * Creates an instance of a subclass of AV.Object for the given classname.
+ * @private
+ */
+
+
+ AV.Object._create = function (className, attributes, options) {
+ var ObjectClass = AV.Object._getSubclass(className);
+
+ return new ObjectClass(attributes, options);
+ }; // Set up a map of className to class so that we can create new instances of
+ // AV Objects from JSON automatically.
+
+
+ AV.Object._classMap = {};
+ AV.Object._extend = AV._extend;
+ /**
+ * Creates a new model with defined attributes,
+ * It's the same with
+ * + * new AV.Object(attributes, options); + *+ * @param {Object} attributes The initial set of data to store in the object. + * @param {Object} options A set of Backbone-like options for creating the + * object. The only option currently supported is "collection". + * @return {AV.Object} + * @since v0.4.4 + * @see AV.Object + * @see AV.Object.extend + */ + + AV.Object['new'] = function (attributes, options) { + return new AV.Object(attributes, options); + }; + /** + * Creates a new subclass of AV.Object for the given AV class name. + * + *
Every extension of a AV class will inherit from the most recent + * previous extension of that class. When a AV.Object is automatically + * created by parsing JSON, it will use the most recent extension of that + * class.
+ * + * @example + * var MyClass = AV.Object.extend("MyClass", { + * // Instance properties + * }, { + * // Class properties + * }); + * + * @param {String} className The name of the AV class backing this model. + * @param {Object} protoProps Instance properties to add to instances of the + * class returned from this method. + * @param {Object} classProps Class properties to add the class returned from + * this method. + * @return {Class} A new subclass of AV.Object. + */ + + + AV.Object.extend = function (className, protoProps, classProps) { + // Handle the case with only two args. + if (!_.isString(className)) { + if (className && _.has(className, 'className')) { + return AV.Object.extend(className.className, className, protoProps); + } else { + throw new Error("AV.Object.extend's first argument should be the className."); + } + } // If someone tries to subclass "User", coerce it to the right type. + + + if (className === 'User') { + className = '_User'; + } + + var NewClassObject = null; + + if (_.has(AV.Object._classMap, className)) { + var OldClassObject = AV.Object._classMap[className]; // This new subclass has been told to extend both from "this" and from + // OldClassObject. This is multiple inheritance, which isn't supported. + // For now, let's just pick one. + + if (protoProps || classProps) { + NewClassObject = OldClassObject._extend(protoProps, classProps); + } else { + return OldClassObject; + } + } else { + protoProps = protoProps || {}; + protoProps._className = className; + NewClassObject = this._extend(protoProps, classProps); + } // Extending a subclass should reuse the classname automatically. + + + NewClassObject.extend = function (arg0) { + var _context4; + + if (_.isString(arg0) || arg0 && _.has(arg0, 'className')) { + return AV.Object.extend.apply(NewClassObject, arguments); + } + + var newArguments = (0, _concat.default)(_context4 = [className]).call(_context4, _.toArray(arguments)); + return AV.Object.extend.apply(NewClassObject, newArguments); + }; // Add the query property descriptor. + + + (0, _defineProperty.default)(NewClassObject, 'query', (0, _getOwnPropertyDescriptor.default)(AV.Object, 'query')); + + NewClassObject['new'] = function (attributes, options) { + return new NewClassObject(attributes, options); + }; + + AV.Object._classMap[className] = NewClassObject; + return NewClassObject; + }; // ES6 class syntax support + + + (0, _defineProperty.default)(AV.Object.prototype, 'className', { + get: function get() { + var className = this._className || this.constructor._LCClassName || this.constructor.name; // If someone tries to subclass "User", coerce it to the right type. + + if (className === 'User') { + return '_User'; + } + + return className; + } + }); + /** + * Register a class. + * If a subclass ofAV.Object
is defined with your own implement
+ * rather then AV.Object.extend
, the subclass must be registered.
+ * @param {Function} klass A subclass of AV.Object
+ * @param {String} [name] Specify the name of the class. Useful when the class might be uglified.
+ * @example
+ * class Person extend AV.Object {}
+ * AV.Object.register(Person);
+ */
+
+ AV.Object.register = function (klass, name) {
+ if (!(klass.prototype instanceof AV.Object)) {
+ throw new Error('registered class is not a subclass of AV.Object');
+ }
+
+ var className = name || klass.name;
+
+ if (!className.length) {
+ throw new Error('registered class must be named');
+ }
+
+ if (name) {
+ klass._LCClassName = name;
+ }
+
+ AV.Object._classMap[className] = klass;
+ };
+ /**
+ * Get a new Query of the current class
+ * @name query
+ * @memberof AV.Object
+ * @type AV.Query
+ * @readonly
+ * @since v3.1.0
+ * @example
+ * const Post = AV.Object.extend('Post');
+ * Post.query.equalTo('author', 'leancloud').find().then();
+ */
+
+
+ (0, _defineProperty.default)(AV.Object, 'query', {
+ get: function get() {
+ return new AV.Query(this.prototype.className);
+ }
+ });
+
+ AV.Object._findUnsavedChildren = function (objects, children, files) {
+ AV._traverse(objects, function (object) {
+ if (object instanceof AV.Object) {
+ if (object.dirty()) {
+ children.push(object);
+ }
+
+ return;
+ }
+
+ if (object instanceof AV.File) {
+ if (!object.id) {
+ files.push(object);
+ }
+
+ return;
+ }
+ });
+ };
+
+ AV.Object._canBeSerializedAsValue = function (object) {
+ var canBeSerializedAsValue = true;
+
+ if (object instanceof AV.Object || object instanceof AV.File) {
+ canBeSerializedAsValue = !!object.id;
+ } else if (_.isArray(object)) {
+ AV._arrayEach(object, function (child) {
+ if (!AV.Object._canBeSerializedAsValue(child)) {
+ canBeSerializedAsValue = false;
+ }
+ });
+ } else if (_.isObject(object)) {
+ AV._objectEach(object, function (child) {
+ if (!AV.Object._canBeSerializedAsValue(child)) {
+ canBeSerializedAsValue = false;
+ }
+ });
+ }
+
+ return canBeSerializedAsValue;
+ };
+
+ AV.Object._deepSaveAsync = function (object, model, options) {
+ var unsavedChildren = [];
+ var unsavedFiles = [];
+
+ AV.Object._findUnsavedChildren(object, unsavedChildren, unsavedFiles);
+
+ unsavedFiles = _.uniq(unsavedFiles);
+
+ var promise = _promise.default.resolve();
+
+ _.each(unsavedFiles, function (file) {
+ promise = promise.then(function () {
+ return file.save();
+ });
+ });
+
+ var objects = _.uniq(unsavedChildren);
+
+ var remaining = _.uniq(objects);
+
+ return promise.then(function () {
+ return continueWhile(function () {
+ return remaining.length > 0;
+ }, function () {
+ // Gather up all the objects that can be saved in this batch.
+ var batch = [];
+ var newRemaining = [];
+
+ AV._arrayEach(remaining, function (object) {
+ if (object._canBeSerialized()) {
+ batch.push(object);
+ } else {
+ newRemaining.push(object);
+ }
+ });
+
+ remaining = newRemaining; // If we can't save any objects, there must be a circular reference.
+
+ if (batch.length === 0) {
+ return _promise.default.reject(new AVError(AVError.OTHER_CAUSE, 'Tried to save a batch with a cycle.'));
+ } // Reserve a spot in every object's save queue.
+
+
+ var readyToStart = _promise.default.resolve((0, _map.default)(_).call(_, batch, function (object) {
+ return object._allPreviousSaves || _promise.default.resolve();
+ })); // Save a single batch, whether previous saves succeeded or failed.
+
+
+ var bathSavePromise = readyToStart.then(function () {
+ return _request('batch', null, null, 'POST', {
+ requests: (0, _map.default)(_).call(_, batch, function (object) {
+ var method = object.id ? 'PUT' : 'POST';
+
+ var json = object._getSaveJSON();
+
+ _.extend(json, object._flags);
+
+ var route = 'classes';
+ var className = object.className;
+ var path = "/".concat(route, "/").concat(className);
+
+ if (object.className === '_User' && !object.id) {
+ // Special-case user sign-up.
+ path = '/users';
+ }
+
+ var path = "/1.1".concat(path);
+
+ if (object.id) {
+ path = path + '/' + object.id;
+ }
+
+ object._startSave();
+
+ return {
+ method: method,
+ path: path,
+ body: json,
+ params: options && options.fetchWhenSave ? {
+ fetchWhenSave: true
+ } : undefined
+ };
+ })
+ }, options).then(function (response) {
+ var results = (0, _map.default)(_).call(_, batch, function (object, i) {
+ if (response[i].success) {
+ object._finishSave(object.parse(response[i].success));
+
+ return object;
+ }
+
+ object._cancelSave();
+
+ return new AVError(response[i].error.code, response[i].error.error);
+ });
+ return handleBatchResults(results);
+ });
+ });
+
+ AV._arrayEach(batch, function (object) {
+ object._allPreviousSaves = bathSavePromise;
+ });
+
+ return bathSavePromise;
+ });
+ }).then(function () {
+ return object;
+ });
+ };
+};
+
+/***/ }),
+/* 501 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var arrayWithHoles = __webpack_require__(502);
+
+var iterableToArrayLimit = __webpack_require__(510);
+
+var unsupportedIterableToArray = __webpack_require__(511);
+
+var nonIterableRest = __webpack_require__(521);
+
+function _slicedToArray(arr, i) {
+ return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
+}
+
+module.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
+
+/***/ }),
+/* 502 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var _Array$isArray = __webpack_require__(503);
+
+function _arrayWithHoles(arr) {
+ if (_Array$isArray(arr)) return arr;
+}
+
+module.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
+
+/***/ }),
+/* 503 */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(504);
+
+/***/ }),
+/* 504 */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(505);
+
+
+/***/ }),
+/* 505 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(506);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 506 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(507);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 507 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(508);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 508 */
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__(509);
+var path = __webpack_require__(13);
+
+module.exports = path.Array.isArray;
+
+
+/***/ }),
+/* 509 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var $ = __webpack_require__(0);
+var isArray = __webpack_require__(80);
+
+// `Array.isArray` method
+// https://tc39.es/ecma262/#sec-array.isarray
+$({ target: 'Array', stat: true }, {
+ isArray: isArray
+});
+
+
+/***/ }),
+/* 510 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var _Symbol = __webpack_require__(225);
+
+var _getIteratorMethod = __webpack_require__(231);
+
+function _iterableToArrayLimit(arr, i) {
+ var _i = arr == null ? null : typeof _Symbol !== "undefined" && _getIteratorMethod(arr) || arr["@@iterator"];
+
+ if (_i == null) return;
+ var _arr = [];
+ var _n = true;
+ var _d = false;
+
+ var _s, _e;
+
+ try {
+ for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
+ _arr.push(_s.value);
+
+ if (i && _arr.length === i) break;
+ }
+ } catch (err) {
+ _d = true;
+ _e = err;
+ } finally {
+ try {
+ if (!_n && _i["return"] != null) _i["return"]();
+ } finally {
+ if (_d) throw _e;
+ }
+ }
+
+ return _arr;
+}
+
+module.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports;
+
+/***/ }),
+/* 511 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var _sliceInstanceProperty = __webpack_require__(512);
+
+var _Array$from = __webpack_require__(516);
+
+var arrayLikeToArray = __webpack_require__(520);
+
+function _unsupportedIterableToArray(o, minLen) {
+ var _context;
+
+ if (!o) return;
+ if (typeof o === "string") return arrayLikeToArray(o, minLen);
+
+ var n = _sliceInstanceProperty(_context = Object.prototype.toString.call(o)).call(_context, 8, -1);
+
+ if (n === "Object" && o.constructor) n = o.constructor.name;
+ if (n === "Map" || n === "Set") return _Array$from(o);
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
+}
+
+module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
+
+/***/ }),
+/* 512 */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(513);
+
+/***/ }),
+/* 513 */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(514);
+
+
+/***/ }),
+/* 514 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(515);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 515 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(222);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 516 */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(517);
+
+/***/ }),
+/* 517 */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(518);
+
+
+/***/ }),
+/* 518 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(519);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 519 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(230);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 520 */
+/***/ (function(module, exports) {
+
+function _arrayLikeToArray(arr, len) {
+ if (len == null || len > arr.length) len = arr.length;
+
+ for (var i = 0, arr2 = new Array(len); i < len; i++) {
+ arr2[i] = arr[i];
+ }
+
+ return arr2;
+}
+
+module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
+
+/***/ }),
+/* 521 */
+/***/ (function(module, exports) {
+
+function _nonIterableRest() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+}
+
+module.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports;
+
+/***/ }),
+/* 522 */
+/***/ (function(module, exports, __webpack_require__) {
+
+module.exports = __webpack_require__(523);
+
+/***/ }),
+/* 523 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var parent = __webpack_require__(524);
+
+module.exports = parent;
+
+
+/***/ }),
+/* 524 */
+/***/ (function(module, exports, __webpack_require__) {
+
+__webpack_require__(525);
+var path = __webpack_require__(13);
+
+var Object = path.Object;
+
+var getOwnPropertyDescriptor = module.exports = function getOwnPropertyDescriptor(it, key) {
+ return Object.getOwnPropertyDescriptor(it, key);
+};
+
+if (Object.getOwnPropertyDescriptor.sham) getOwnPropertyDescriptor.sham = true;
+
+
+/***/ }),
+/* 525 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var $ = __webpack_require__(0);
+var fails = __webpack_require__(4);
+var toIndexedObject = __webpack_require__(33);
+var nativeGetOwnPropertyDescriptor = __webpack_require__(64).f;
+var DESCRIPTORS = __webpack_require__(19);
+
+var FAILS_ON_PRIMITIVES = fails(function () { nativeGetOwnPropertyDescriptor(1); });
+var FORCED = !DESCRIPTORS || FAILS_ON_PRIMITIVES;
+
+// `Object.getOwnPropertyDescriptor` method
+// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
+$({ target: 'Object', stat: true, forced: FORCED, sham: !DESCRIPTORS }, {
+ getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) {
+ return nativeGetOwnPropertyDescriptor(toIndexedObject(it), key);
+ }
+});
+
+
+/***/ }),
+/* 526 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _ = __webpack_require__(1);
+
+var AVError = __webpack_require__(40);
+
+module.exports = function (AV) {
+ AV.Role = AV.Object.extend('_Role',
+ /** @lends AV.Role.prototype */
+ {
+ // Instance Methods
+
+ /**
+ * Represents a Role on the AV server. Roles represent groupings of
+ * Users for the purposes of granting permissions (e.g. specifying an ACL
+ * for an Object). Roles are specified by their sets of child users and
+ * child roles, all of which are granted any permissions that the parent
+ * role has.
+ *
+ * Roles must have a name (which cannot be changed after creation of the + * role), and must specify an ACL.
+ * An AV.Role is a local representation of a role persisted to the AV + * cloud. + * @class AV.Role + * @param {String} name The name of the Role to create. + * @param {AV.ACL} acl The ACL for this role. + */ + constructor: function constructor(name, acl) { + if (_.isString(name)) { + AV.Object.prototype.constructor.call(this, null, null); + this.setName(name); + } else { + AV.Object.prototype.constructor.call(this, name, acl); + } + + if (acl) { + if (!(acl instanceof AV.ACL)) { + throw new TypeError('acl must be an instance of AV.ACL'); + } else { + this.setACL(acl); + } + } + }, + + /** + * Gets the name of the role. You can alternatively call role.get("name") + * + * @return {String} the name of the role. + */ + getName: function getName() { + return this.get('name'); + }, + + /** + * Sets the name for a role. This value must be set before the role has + * been saved to the server, and cannot be set once the role has been + * saved. + * + *+ * A role's name can only contain alphanumeric characters, _, -, and + * spaces. + *
+ * + *This is equivalent to calling role.set("name", name)
+ * + * @param {String} name The name of the role. + */ + setName: function setName(name, options) { + return this.set('name', name, options); + }, + + /** + * Gets the AV.Relation for the AV.Users that are direct + * children of this role. These users are granted any privileges that this + * role has been granted (e.g. read or write access through ACLs). You can + * add or remove users from the role through this relation. + * + *This is equivalent to calling role.relation("users")
+ * + * @return {AV.Relation} the relation for the users belonging to this + * role. + */ + getUsers: function getUsers() { + return this.relation('users'); + }, + + /** + * Gets the AV.Relation for the AV.Roles that are direct + * children of this role. These roles' users are granted any privileges that + * this role has been granted (e.g. read or write access through ACLs). You + * can add or remove child roles from this role through this relation. + * + *This is equivalent to calling role.relation("roles")
+ * + * @return {AV.Relation} the relation for the roles belonging to this + * role. + */ + getRoles: function getRoles() { + return this.relation('roles'); + }, + + /** + * @ignore + */ + validate: function validate(attrs, options) { + if ('name' in attrs && attrs.name !== this.getName()) { + var newName = attrs.name; + + if (this.id && this.id !== attrs.objectId) { + // Check to see if the objectId being set matches this.id. + // This happens during a fetch -- the id is set before calling fetch. + // Let the name be set in this case. + return new AVError(AVError.OTHER_CAUSE, "A role's name can only be set before it has been saved."); + } + + if (!_.isString(newName)) { + return new AVError(AVError.OTHER_CAUSE, "A role's name must be a String."); + } + + if (!/^[0-9a-zA-Z\-_ ]+$/.test(newName)) { + return new AVError(AVError.OTHER_CAUSE, "A role's name can only contain alphanumeric characters, _," + ' -, and spaces.'); + } + } + + if (AV.Object.prototype.validate) { + return AV.Object.prototype.validate.call(this, attrs, options); + } + + return false; + } + }); +}; + +/***/ }), +/* 527 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(2); + +var _defineProperty2 = _interopRequireDefault(__webpack_require__(528)); + +var _promise = _interopRequireDefault(__webpack_require__(10)); + +var _map = _interopRequireDefault(__webpack_require__(39)); + +var _find = _interopRequireDefault(__webpack_require__(104)); + +var _stringify = _interopRequireDefault(__webpack_require__(34)); + +var _ = __webpack_require__(1); + +var uuid = __webpack_require__(214); + +var AVError = __webpack_require__(40); + +var _require = __webpack_require__(25), + AVRequest = _require._request, + request = _require.request; + +var _require2 = __webpack_require__(61), + getAdapter = _require2.getAdapter; + +var PLATFORM_ANONYMOUS = 'anonymous'; +var PLATFORM_QQAPP = 'lc_qqapp'; + +var mergeUnionDataIntoAuthData = function mergeUnionDataIntoAuthData() { + var defaultUnionIdPlatform = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'weixin'; + return function (authData, unionId) { + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + _ref$unionIdPlatform = _ref.unionIdPlatform, + unionIdPlatform = _ref$unionIdPlatform === void 0 ? defaultUnionIdPlatform : _ref$unionIdPlatform, + _ref$asMainAccount = _ref.asMainAccount, + asMainAccount = _ref$asMainAccount === void 0 ? false : _ref$asMainAccount; + + if (typeof unionId !== 'string') throw new AVError(AVError.OTHER_CAUSE, 'unionId is not a string'); + if (typeof unionIdPlatform !== 'string') throw new AVError(AVError.OTHER_CAUSE, 'unionIdPlatform is not a string'); + return _.extend({}, authData, { + platform: unionIdPlatform, + unionid: unionId, + main_account: Boolean(asMainAccount) + }); + }; +}; + +module.exports = function (AV) { + /** + * @class + * + *An AV.User object is a local representation of a user persisted to the + * LeanCloud server. This class is a subclass of an AV.Object, and retains the + * same functionality of an AV.Object, but also extends it with various + * user specific methods, like authentication, signing up, and validation of + * uniqueness.
+ */ + AV.User = AV.Object.extend('_User', + /** @lends AV.User.prototype */ + { + // Instance Variables + _isCurrentUser: false, + // Instance Methods + + /** + * Internal method to handle special fields in a _User response. + * @private + */ + _mergeMagicFields: function _mergeMagicFields(attrs) { + if (attrs.sessionToken) { + this._sessionToken = attrs.sessionToken; + delete attrs.sessionToken; + } + + return AV.User.__super__._mergeMagicFields.call(this, attrs); + }, + + /** + * Removes null values from authData (which exist temporarily for + * unlinking) + * @private + */ + _cleanupAuthData: function _cleanupAuthData() { + if (!this.isCurrent()) { + return; + } + + var authData = this.get('authData'); + + if (!authData) { + return; + } + + AV._objectEach(this.get('authData'), function (value, key) { + if (!authData[key]) { + delete authData[key]; + } + }); + }, + + /** + * Synchronizes authData for all providers. + * @private + */ + _synchronizeAllAuthData: function _synchronizeAllAuthData() { + var authData = this.get('authData'); + + if (!authData) { + return; + } + + var self = this; + + AV._objectEach(this.get('authData'), function (value, key) { + self._synchronizeAuthData(key); + }); + }, + + /** + * Synchronizes auth data for a provider (e.g. puts the access token in the + * right place to be used by the Facebook SDK). + * @private + */ + _synchronizeAuthData: function _synchronizeAuthData(provider) { + if (!this.isCurrent()) { + return; + } + + var authType; + + if (_.isString(provider)) { + authType = provider; + provider = AV.User._authProviders[authType]; + } else { + authType = provider.getAuthType(); + } + + var authData = this.get('authData'); + + if (!authData || !provider) { + return; + } + + var success = provider.restoreAuthentication(authData[authType]); + + if (!success) { + this.dissociateAuthData(provider); + } + }, + _handleSaveResult: function _handleSaveResult(makeCurrent) { + // Clean up and synchronize the authData object, removing any unset values + if (makeCurrent && !AV._config.disableCurrentUser) { + this._isCurrentUser = true; + } + + this._cleanupAuthData(); + + this._synchronizeAllAuthData(); // Don't keep the password around. + + + delete this._serverData.password; + + this._rebuildEstimatedDataForKey('password'); + + this._refreshCache(); + + if ((makeCurrent || this.isCurrent()) && !AV._config.disableCurrentUser) { + // Some old version of leanengine-node-sdk will overwrite + // AV.User._saveCurrentUser which returns no Promise. + // So we need a Promise wrapper. + return _promise.default.resolve(AV.User._saveCurrentUser(this)); + } else { + return _promise.default.resolve(); + } + }, + + /** + * Unlike in the Android/iOS SDKs, logInWith is unnecessary, since you can + * call linkWith on the user (even if it doesn't exist yet on the server). + * @private + */ + _linkWith: function _linkWith(provider, data) { + var _this = this; + + var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + _ref2$failOnNotExist = _ref2.failOnNotExist, + failOnNotExist = _ref2$failOnNotExist === void 0 ? false : _ref2$failOnNotExist, + useMasterKey = _ref2.useMasterKey, + sessionToken = _ref2.sessionToken, + user = _ref2.user; + + var authType; + + if (_.isString(provider)) { + authType = provider; + provider = AV.User._authProviders[provider]; + } else { + authType = provider.getAuthType(); + } + + if (data) { + return this.save({ + authData: (0, _defineProperty2.default)({}, authType, data) + }, { + useMasterKey: useMasterKey, + sessionToken: sessionToken, + user: user, + fetchWhenSave: !!this.get('authData'), + _failOnNotExist: failOnNotExist + }).then(function (model) { + return model._handleSaveResult(true).then(function () { + return model; + }); + }); + } else { + return provider.authenticate().then(function (result) { + return _this._linkWith(provider, result); + }); + } + }, + + /** + * Associate the user with a third party authData. + * @since 3.3.0 + * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 } + * @param {string} platform Available platform for sign up. + * @return {Promisecurrent
.
+ *
+ * A username and password must be set before calling signUp.
+ * + * @param {Object} attrs Extra fields to set on the new user, or null. + * @param {AuthOptions} options + * @return {Promise} A promise that is fulfilled when the signup + * finishes. + * @see AV.User.signUp + */ + signUp: function signUp(attrs, options) { + var error; + var username = attrs && attrs.username || this.get('username'); + + if (!username || username === '') { + error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up user with an empty name.'); + throw error; + } + + var password = attrs && attrs.password || this.get('password'); + + if (!password || password === '') { + error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up user with an empty password.'); + throw error; + } + + return this.save(attrs, options).then(function (model) { + if (model.isAnonymous()) { + model.unset("authData.".concat(PLATFORM_ANONYMOUS)); + model._opSetQueue = [{}]; + } + + return model._handleSaveResult(true).then(function () { + return model; + }); + }); + }, + + /** + * Signs up a new user with mobile phone and sms code. + * You should call this instead of save for + * new AV.Users. This will create a new AV.User on the server, and + * also persist the session on disk so that you can access the user using + *current
.
+ *
+ * A username and password must be set before calling signUp.
+ * + * @param {Object} attrs Extra fields to set on the new user, or null. + * @param {AuthOptions} options + * @return {Promise} A promise that is fulfilled when the signup + * finishes. + * @see AV.User.signUpOrlogInWithMobilePhone + * @see AV.Cloud.requestSmsCode + */ + signUpOrlogInWithMobilePhone: function signUpOrlogInWithMobilePhone(attrs) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var error; + var mobilePhoneNumber = attrs && attrs.mobilePhoneNumber || this.get('mobilePhoneNumber'); + + if (!mobilePhoneNumber || mobilePhoneNumber === '') { + error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up or login user by mobilePhoneNumber ' + 'with an empty mobilePhoneNumber.'); + throw error; + } + + var smsCode = attrs && attrs.smsCode || this.get('smsCode'); + + if (!smsCode || smsCode === '') { + error = new AVError(AVError.OTHER_CAUSE, 'Cannot sign up or login user by mobilePhoneNumber ' + 'with an empty smsCode.'); + throw error; + } + + options._makeRequest = function (route, className, id, method, json) { + return AVRequest('usersByMobilePhone', null, null, 'POST', json); + }; + + return this.save(attrs, options).then(function (model) { + delete model.attributes.smsCode; + delete model._serverData.smsCode; + return model._handleSaveResult(true).then(function () { + return model; + }); + }); + }, + + /** + * The same with {@link AV.User.loginWithAuthData}, except that you can set attributes before login. + * @since 3.7.0 + */ + loginWithAuthData: function loginWithAuthData(authData, platform, options) { + return this._linkWith(platform, authData, options); + }, + + /** + * The same with {@link AV.User.loginWithAuthDataAndUnionId}, except that you can set attributes before login. + * @since 3.7.0 + */ + loginWithAuthDataAndUnionId: function loginWithAuthDataAndUnionId(authData, platform, unionId, unionLoginOptions) { + return this.loginWithAuthData(mergeUnionDataIntoAuthData()(authData, unionId, unionLoginOptions), platform, unionLoginOptions); + }, + + /** + * The same with {@link AV.User.loginWithWeapp}, except that you can set attributes before login. + * @deprecated please use {@link AV.User#loginWithMiniApp} + * @since 3.7.0 + * @param {Object} [options] + * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists. + * @param {boolean} [options.preferUnionId] 当用户满足 {@link https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html 获取 UnionId 的条件} 时,是否使用 UnionId 登录。(since 3.13.0) + * @param {string} [options.unionIdPlatform = 'weixin'] (only take effect when preferUnionId) unionId platform + * @param {boolean} [options.asMainAccount = true] (only take effect when preferUnionId) If true, the unionId will be associated with the user. + * @return {Promisecurrent
.
+ *
+ * A username and password must be set before calling logIn.
+ * + * @see AV.User.logIn + * @return {Promise} A promise that is fulfilled with the user when + * the login is complete. + */ + logIn: function logIn() { + var model = this; + var request = AVRequest('login', null, null, 'POST', this.toJSON()); + return request.then(function (resp) { + var serverAttrs = model.parse(resp); + + model._finishFetch(serverAttrs); + + return model._handleSaveResult(true).then(function () { + if (!serverAttrs.smsCode) delete model.attributes['smsCode']; + return model; + }); + }); + }, + + /** + * @see AV.Object#save + */ + save: function save(arg1, arg2, arg3) { + var attrs, options; + + if (_.isObject(arg1) || _.isNull(arg1) || _.isUndefined(arg1)) { + attrs = arg1; + options = arg2; + } else { + attrs = {}; + attrs[arg1] = arg2; + options = arg3; + } + + options = options || {}; + return AV.Object.prototype.save.call(this, attrs, options).then(function (model) { + return model._handleSaveResult(false).then(function () { + return model; + }); + }); + }, + + /** + * Follow a user + * @since 0.3.0 + * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user. + * @param {AV.User | String} options.user The target user or user's objectId to follow. + * @param {Object} [options.attributes] key-value attributes dictionary to be used as + * conditions of followerQuery/followeeQuery. + * @param {AuthOptions} [authOptions] + */ + follow: function follow(options, authOptions) { + if (!this.id) { + throw new Error('Please signin.'); + } + + var user; + var attributes; + + if (options.user) { + user = options.user; + attributes = options.attributes; + } else { + user = options; + } + + var userObjectId = _.isString(user) ? user : user.id; + + if (!userObjectId) { + throw new Error('Invalid target user.'); + } + + var route = 'users/' + this.id + '/friendship/' + userObjectId; + var request = AVRequest(route, null, null, 'POST', AV._encode(attributes), authOptions); + return request; + }, + + /** + * Unfollow a user. + * @since 0.3.0 + * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user. + * @param {AV.User | String} options.user The target user or user's objectId to unfollow. + * @param {AuthOptions} [authOptions] + */ + unfollow: function unfollow(options, authOptions) { + if (!this.id) { + throw new Error('Please signin.'); + } + + var user; + + if (options.user) { + user = options.user; + } else { + user = options; + } + + var userObjectId = _.isString(user) ? user : user.id; + + if (!userObjectId) { + throw new Error('Invalid target user.'); + } + + var route = 'users/' + this.id + '/friendship/' + userObjectId; + var request = AVRequest(route, null, null, 'DELETE', null, authOptions); + return request; + }, + + /** + * Get the user's followers and followees. + * @since 4.8.0 + * @param {Object} [options] + * @param {Number} [options.skip] + * @param {Number} [options.limit] + * @param {AuthOptions} [authOptions] + */ + getFollowersAndFollowees: function getFollowersAndFollowees(options, authOptions) { + if (!this.id) { + throw new Error('Please signin.'); + } + + return request({ + method: 'GET', + path: "/users/".concat(this.id, "/followersAndFollowees"), + query: { + skip: options && options.skip, + limit: options && options.limit, + include: 'follower,followee', + keys: 'follower,followee' + }, + authOptions: authOptions + }).then(function (_ref11) { + var followers = _ref11.followers, + followees = _ref11.followees; + return { + followers: (0, _map.default)(followers).call(followers, function (_ref12) { + var follower = _ref12.follower; + return AV._decode(follower); + }), + followees: (0, _map.default)(followees).call(followees, function (_ref13) { + var followee = _ref13.followee; + return AV._decode(followee); + }) + }; + }); + }, + + /** + *Create a follower query to query the user's followers. + * @since 0.3.0 + * @see AV.User#followerQuery + */ + followerQuery: function followerQuery() { + return AV.User.followerQuery(this.id); + }, + + /** + *Create a followee query to query the user's followees. + * @since 0.3.0 + * @see AV.User#followeeQuery + */ + followeeQuery: function followeeQuery() { + return AV.User.followeeQuery(this.id); + }, + + /** + * @see AV.Object#fetch + */ + fetch: function fetch(fetchOptions, options) { + return AV.Object.prototype.fetch.call(this, fetchOptions, options).then(function (model) { + return model._handleSaveResult(false).then(function () { + return model; + }); + }); + }, + + /** + * Update user's new password safely based on old password. + * @param {String} oldPassword the old password. + * @param {String} newPassword the new password. + * @param {AuthOptions} options + */ + updatePassword: function updatePassword(oldPassword, newPassword, options) { + var _this12 = this; + + var route = 'users/' + this.id + '/updatePassword'; + var params = { + old_password: oldPassword, + new_password: newPassword + }; + var request = AVRequest(route, null, null, 'PUT', params, options); + return request.then(function (resp) { + _this12._finishFetch(_this12.parse(resp)); + + return _this12._handleSaveResult(true).then(function () { + return resp; + }); + }); + }, + + /** + * Returns true ifcurrent
would return this user.
+ * @see AV.User#current
+ */
+ isCurrent: function isCurrent() {
+ return this._isCurrentUser;
+ },
+
+ /**
+ * Returns get("username").
+ * @return {String}
+ * @see AV.Object#get
+ */
+ getUsername: function getUsername() {
+ return this.get('username');
+ },
+
+ /**
+ * Returns get("mobilePhoneNumber").
+ * @return {String}
+ * @see AV.Object#get
+ */
+ getMobilePhoneNumber: function getMobilePhoneNumber() {
+ return this.get('mobilePhoneNumber');
+ },
+
+ /**
+ * Calls set("mobilePhoneNumber", phoneNumber, options) and returns the result.
+ * @param {String} mobilePhoneNumber
+ * @return {Boolean}
+ * @see AV.Object#set
+ */
+ setMobilePhoneNumber: function setMobilePhoneNumber(phone, options) {
+ return this.set('mobilePhoneNumber', phone, options);
+ },
+
+ /**
+ * Calls set("username", username, options) and returns the result.
+ * @param {String} username
+ * @return {Boolean}
+ * @see AV.Object#set
+ */
+ setUsername: function setUsername(username, options) {
+ return this.set('username', username, options);
+ },
+
+ /**
+ * Calls set("password", password, options) and returns the result.
+ * @param {String} password
+ * @return {Boolean}
+ * @see AV.Object#set
+ */
+ setPassword: function setPassword(password, options) {
+ return this.set('password', password, options);
+ },
+
+ /**
+ * Returns get("email").
+ * @return {String}
+ * @see AV.Object#get
+ */
+ getEmail: function getEmail() {
+ return this.get('email');
+ },
+
+ /**
+ * Calls set("email", email, options) and returns the result.
+ * @param {String} email
+ * @param {AuthOptions} options
+ * @return {Boolean}
+ * @see AV.Object#set
+ */
+ setEmail: function setEmail(email, options) {
+ return this.set('email', email, options);
+ },
+
+ /**
+ * Checks whether this user is the current user and has been authenticated.
+ * @deprecated 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),
+ * 如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id
+ * @return (Boolean) whether this user is the current user and is logged in.
+ */
+ authenticated: function authenticated() {
+ console.warn('DEPRECATED: 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id。');
+ return !!this._sessionToken && !AV._config.disableCurrentUser && AV.User.current() && AV.User.current().id === this.id;
+ },
+
+ /**
+ * Detects if current sessionToken is valid.
+ *
+ * @since 2.0.0
+ * @return Promise.current
.
+ *
+ * @param {String} username The username (or email) to log in with.
+ * @param {String} password The password to log in with.
+ * @return {Promise} A promise that is fulfilled with the user when
+ * the login completes.
+ * @see AV.User#logIn
+ */
+ logIn: function logIn(username, password) {
+ var user = AV.Object._create('_User');
+
+ user._finishFetch({
+ username: username,
+ password: password
+ });
+
+ return user.logIn();
+ },
+
+ /**
+ * Logs in a user with a session token. On success, this saves the session
+ * to disk, so you can retrieve the currently logged in user using
+ * current
.
+ *
+ * @param {String} sessionToken The sessionToken to log in with.
+ * @return {Promise} A promise that is fulfilled with the user when
+ * the login completes.
+ */
+ become: function become(sessionToken) {
+ return this._fetchUserBySessionToken(sessionToken).then(function (user) {
+ return user._handleSaveResult(true).then(function () {
+ return user;
+ });
+ });
+ },
+ _fetchUserBySessionToken: function _fetchUserBySessionToken(sessionToken) {
+ if (sessionToken === undefined) {
+ return _promise.default.reject(new Error('The sessionToken cannot be undefined'));
+ }
+
+ var user = AV.Object._create('_User');
+
+ return request({
+ method: 'GET',
+ path: '/users/me',
+ authOptions: {
+ sessionToken: sessionToken
+ }
+ }).then(function (resp) {
+ var serverAttrs = user.parse(resp);
+
+ user._finishFetch(serverAttrs);
+
+ return user;
+ });
+ },
+
+ /**
+ * Logs in a user with a mobile phone number and sms code sent by
+ * AV.User.requestLoginSmsCode.On success, this
+ * saves the session to disk, so you can retrieve the currently logged in
+ * user using current
.
+ *
+ * @param {String} mobilePhone The user's mobilePhoneNumber
+ * @param {String} smsCode The sms code sent by AV.User.requestLoginSmsCode
+ * @return {Promise} A promise that is fulfilled with the user when
+ * the login completes.
+ * @see AV.User#logIn
+ */
+ logInWithMobilePhoneSmsCode: function logInWithMobilePhoneSmsCode(mobilePhone, smsCode) {
+ var user = AV.Object._create('_User');
+
+ user._finishFetch({
+ mobilePhoneNumber: mobilePhone,
+ smsCode: smsCode
+ });
+
+ return user.logIn();
+ },
+
+ /**
+ * Signs up or logs in a user with a mobilePhoneNumber and smsCode.
+ * On success, this saves the session to disk, so you can retrieve the currently
+ * logged in user using current
.
+ *
+ * @param {String} mobilePhoneNumber The user's mobilePhoneNumber.
+ * @param {String} smsCode The sms code sent by AV.Cloud.requestSmsCode
+ * @param {Object} attributes The user's other attributes such as username etc.
+ * @param {AuthOptions} options
+ * @return {Promise} A promise that is fulfilled with the user when
+ * the login completes.
+ * @see AV.User#signUpOrlogInWithMobilePhone
+ * @see AV.Cloud.requestSmsCode
+ */
+ signUpOrlogInWithMobilePhone: function signUpOrlogInWithMobilePhone(mobilePhoneNumber, smsCode, attrs, options) {
+ attrs = attrs || {};
+ attrs.mobilePhoneNumber = mobilePhoneNumber;
+ attrs.smsCode = smsCode;
+
+ var user = AV.Object._create('_User');
+
+ return user.signUpOrlogInWithMobilePhone(attrs, options);
+ },
+
+ /**
+ * Logs in a user with a mobile phone number and password. On success, this
+ * saves the session to disk, so you can retrieve the currently logged in
+ * user using current
.
+ *
+ * @param {String} mobilePhone The user's mobilePhoneNumber
+ * @param {String} password The password to log in with.
+ * @return {Promise} A promise that is fulfilled with the user when
+ * the login completes.
+ * @see AV.User#logIn
+ */
+ logInWithMobilePhone: function logInWithMobilePhone(mobilePhone, password) {
+ var user = AV.Object._create('_User');
+
+ user._finishFetch({
+ mobilePhoneNumber: mobilePhone,
+ password: password
+ });
+
+ return user.logIn();
+ },
+
+ /**
+ * Logs in a user with email and password.
+ *
+ * @since 3.13.0
+ * @param {String} email The user's email.
+ * @param {String} password The password to log in with.
+ * @return {Promise} A promise that is fulfilled with the user when
+ * the login completes.
+ */
+ loginWithEmail: function loginWithEmail(email, password) {
+ var user = AV.Object._create('_User');
+
+ user._finishFetch({
+ email: email,
+ password: password
+ });
+
+ return user.logIn();
+ },
+
+ /**
+ * Signs up or logs in a user with a third party auth data(AccessToken).
+ * On success, this saves the session to disk, so you can retrieve the currently
+ * logged in user using current
.
+ *
+ * @since 3.7.0
+ * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }
+ * @param {string} platform Available platform for sign up.
+ * @param {Object} [options]
+ * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists.
+ * @return {Promise} A promise that is fulfilled with the user when
+ * the login completes.
+ * @example AV.User.loginWithAuthData({
+ * openid: 'abc123',
+ * access_token: '123abc',
+ * expires_in: 1382686496
+ * }, 'weixin').then(function(user) {
+ * //Access user here
+ * }).catch(function(error) {
+ * //console.error("error: ", error);
+ * });
+ * @see {@link https://leancloud.cn/docs/js_guide.html#绑定第三方平台账户}
+ */
+ loginWithAuthData: function loginWithAuthData(authData, platform, options) {
+ return AV.User._logInWith(platform, authData, options);
+ },
+
+ /**
+ * @deprecated renamed to {@link AV.User.loginWithAuthData}
+ */
+ signUpOrlogInWithAuthData: function signUpOrlogInWithAuthData() {
+ console.warn('DEPRECATED: User.signUpOrlogInWithAuthData 已废弃,请使用 User#loginWithAuthData 代替');
+ return this.loginWithAuthData.apply(this, arguments);
+ },
+
+ /**
+ * Signs up or logs in a user with a third party authData and unionId.
+ * @since 3.7.0
+ * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }
+ * @param {string} platform Available platform for sign up.
+ * @param {string} unionId
+ * @param {Object} [unionLoginOptions]
+ * @param {string} [unionLoginOptions.unionIdPlatform = 'weixin'] unionId platform
+ * @param {boolean} [unionLoginOptions.asMainAccount = false] If true, the unionId will be associated with the user.
+ * @param {boolean} [unionLoginOptions.failOnNotExist] If true, the login request will fail when no user matches this authData exists.
+ * @return {Promisecurrent
will return null
.
+ * @return {Promise}
+ */
+ logOut: function logOut() {
+ if (AV._config.disableCurrentUser) {
+ console.warn('AV.User.current() was disabled in multi-user environment, call logOut() from user object instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html');
+ return _promise.default.resolve(null);
+ }
+
+ if (AV.User._currentUser !== null) {
+ AV.User._currentUser._logOutWithAll();
+
+ AV.User._currentUser._isCurrentUser = false;
+ }
+
+ AV.User._currentUserMatchesDisk = true;
+ AV.User._currentUser = null;
+ return AV.localStorage.removeItemAsync(AV._getAVPath(AV.User._CURRENT_USER_KEY)).then(function () {
+ return AV._refreshSubscriptionId();
+ });
+ },
+
+ /**
+ *Create a follower query for special user to query the user's followers.
+ * @param {String} userObjectId The user object id.
+ * @return {AV.FriendShipQuery}
+ * @since 0.3.0
+ */
+ followerQuery: function followerQuery(userObjectId) {
+ if (!userObjectId || !_.isString(userObjectId)) {
+ throw new Error('Invalid user object id.');
+ }
+
+ var query = new AV.FriendShipQuery('_Follower');
+ query._friendshipTag = 'follower';
+ query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));
+ return query;
+ },
+
+ /**
+ *Create a followee query for special user to query the user's followees.
+ * @param {String} userObjectId The user object id.
+ * @return {AV.FriendShipQuery}
+ * @since 0.3.0
+ */
+ followeeQuery: function followeeQuery(userObjectId) {
+ if (!userObjectId || !_.isString(userObjectId)) {
+ throw new Error('Invalid user object id.');
+ }
+
+ var query = new AV.FriendShipQuery('_Followee');
+ query._friendshipTag = 'followee';
+ query.equalTo('user', AV.Object.createWithoutData('_User', userObjectId));
+ return query;
+ },
+
+ /**
+ * Requests a password reset email to be sent to the specified email address
+ * associated with the user account. This email allows the user to securely
+ * reset their password on the AV site.
+ *
+ * @param {String} email The email address associated with the user that
+ * forgot their password.
+ * @return {Promise}
+ */
+ requestPasswordReset: function requestPasswordReset(email) {
+ var json = {
+ email: email
+ };
+ var request = AVRequest('requestPasswordReset', null, null, 'POST', json);
+ return request;
+ },
+
+ /**
+ * Requests a verify email to be sent to the specified email address
+ * associated with the user account. This email allows the user to securely
+ * verify their email address on the AV site.
+ *
+ * @param {String} email The email address associated with the user that
+ * doesn't verify their email address.
+ * @return {Promise}
+ */
+ requestEmailVerify: function requestEmailVerify(email) {
+ var json = {
+ email: email
+ };
+ var request = AVRequest('requestEmailVerify', null, null, 'POST', json);
+ return request;
+ },
+
+ /**
+ * Requests a verify sms code to be sent to the specified mobile phone
+ * number associated with the user account. This sms code allows the user to
+ * verify their mobile phone number by calling AV.User.verifyMobilePhone
+ *
+ * @param {String} mobilePhoneNumber The mobile phone number associated with the
+ * user that doesn't verify their mobile phone number.
+ * @param {SMSAuthOptions} [options]
+ * @return {Promise}
+ */
+ requestMobilePhoneVerify: function requestMobilePhoneVerify(mobilePhoneNumber) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ var data = {
+ mobilePhoneNumber: mobilePhoneNumber
+ };
+
+ if (options.validateToken) {
+ data.validate_token = options.validateToken;
+ }
+
+ var request = AVRequest('requestMobilePhoneVerify', null, null, 'POST', data, options);
+ return request;
+ },
+
+ /**
+ * Requests a reset password sms code to be sent to the specified mobile phone
+ * number associated with the user account. This sms code allows the user to
+ * reset their account's password by calling AV.User.resetPasswordBySmsCode
+ *
+ * @param {String} mobilePhoneNumber The mobile phone number associated with the
+ * user that doesn't verify their mobile phone number.
+ * @param {SMSAuthOptions} [options]
+ * @return {Promise}
+ */
+ requestPasswordResetBySmsCode: function requestPasswordResetBySmsCode(mobilePhoneNumber) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ var data = {
+ mobilePhoneNumber: mobilePhoneNumber
+ };
+
+ if (options.validateToken) {
+ data.validate_token = options.validateToken;
+ }
+
+ var request = AVRequest('requestPasswordResetBySmsCode', null, null, 'POST', data, options);
+ return request;
+ },
+
+ /**
+ * Requests a change mobile phone number sms code to be sent to the mobilePhoneNumber.
+ * This sms code allows current user to reset it's mobilePhoneNumber by
+ * calling {@link AV.User.changePhoneNumber}
+ * @since 4.7.0
+ * @param {String} mobilePhoneNumber
+ * @param {Number} [ttl] ttl of sms code (default is 6 minutes)
+ * @param {SMSAuthOptions} [options]
+ * @return {Promise}
+ */
+ requestChangePhoneNumber: function requestChangePhoneNumber(mobilePhoneNumber, ttl, options) {
+ var data = {
+ mobilePhoneNumber: mobilePhoneNumber
+ };
+
+ if (ttl) {
+ data.ttl = options.ttl;
+ }
+
+ if (options && options.validateToken) {
+ data.validate_token = options.validateToken;
+ }
+
+ return AVRequest('requestChangePhoneNumber', null, null, 'POST', data, options);
+ },
+
+ /**
+ * Makes a call to reset user's account mobilePhoneNumber by sms code.
+ * The sms code is sent by {@link AV.User.requestChangePhoneNumber}
+ * @since 4.7.0
+ * @param {String} mobilePhoneNumber
+ * @param {String} code The sms code.
+ * @return {Promise}
+ */
+ changePhoneNumber: function changePhoneNumber(mobilePhoneNumber, code) {
+ var data = {
+ mobilePhoneNumber: mobilePhoneNumber,
+ code: code
+ };
+ return AVRequest('changePhoneNumber', null, null, 'POST', data);
+ },
+
+ /**
+ * Makes a call to reset user's account password by sms code and new password.
+ * The sms code is sent by AV.User.requestPasswordResetBySmsCode.
+ * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode
+ * @param {String} password The new password.
+ * @param {String} mobilePhoneNumber
+ * @return {Promise} A promise that will be resolved with the result
+ * of the function.
+ */
+ resetPasswordBySmsCode: function resetPasswordBySmsCode(code, password, mobilePhoneNumber) {
+ var json = {
+ password: password,
+ mobilePhoneNumber: mobilePhoneNumber
+ };
+ var request = AVRequest('resetPasswordBySmsCode', null, code, 'PUT', json);
+ return request;
+ },
+
+ /**
+ * Makes a call to verify sms code that sent by AV.User.Cloud.requestSmsCode
+ * If verify successfully,the user mobilePhoneVerified attribute will be true.
+ * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode
+ * @param {String} mobilePhoneNumber
+ * @return {Promise} A promise that will be resolved with the result
+ * of the function.
+ */
+ verifyMobilePhone: function verifyMobilePhone(code, mobilePhoneNumber) {
+ var json = {
+ mobilePhoneNumber: mobilePhoneNumber
+ };
+ var request = AVRequest('verifyMobilePhone', null, code, 'POST', json);
+ return request;
+ },
+
+ /**
+ * Requests a logIn sms code to be sent to the specified mobile phone
+ * number associated with the user account. This sms code allows the user to
+ * login by AV.User.logInWithMobilePhoneSmsCode function.
+ *
+ * @param {String} mobilePhoneNumber The mobile phone number associated with the
+ * user that want to login by AV.User.logInWithMobilePhoneSmsCode
+ * @param {SMSAuthOptions} [options]
+ * @return {Promise}
+ */
+ requestLoginSmsCode: function requestLoginSmsCode(mobilePhoneNumber) {
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ var data = {
+ mobilePhoneNumber: mobilePhoneNumber
+ };
+
+ if (options.validateToken) {
+ data.validate_token = options.validateToken;
+ }
+
+ var request = AVRequest('requestLoginSmsCode', null, null, 'POST', data, options);
+ return request;
+ },
+
+ /**
+ * Retrieves the currently logged in AVUser with a valid session,
+ * either from memory or localStorage, if necessary.
+ * @return {Promise.AV.Query defines a query that is used to fetch AV.Objects. The
+ * most common use case is finding all objects that match a query through the
+ * find
method. For example, this sample code fetches all objects
+ * of class MyClass
. It calls a different function depending on
+ * whether the fetch succeeded or not.
+ *
+ *
+ * var query = new AV.Query(MyClass); + * query.find().then(function(results) { + * // results is an array of AV.Object. + * }, function(error) { + * // error is an instance of AVError. + * });+ * + *
An AV.Query can also be used to retrieve a single object whose id is
+ * known, through the get method. For example, this sample code fetches an
+ * object of class MyClass
and id myId
. It calls a
+ * different function depending on whether the fetch succeeded or not.
+ *
+ *
+ * var query = new AV.Query(MyClass); + * query.get(myId).then(function(object) { + * // object is an instance of AV.Object. + * }, function(error) { + * // error is an instance of AVError. + * });+ * + *
An AV.Query can also be used to count the number of objects that match
+ * the query without retrieving all of those objects. For example, this
+ * sample code counts the number of objects of the class MyClass
+ *
+ * var query = new AV.Query(MyClass); + * query.count().then(function(number) { + * // There are number instances of MyClass. + * }, function(error) { + * // error is an instance of AVError. + * });+ */ + AV.Query = function (objectClass) { + if (_.isString(objectClass)) { + objectClass = AV.Object._getSubclass(objectClass); + } + + this.objectClass = objectClass; + this.className = objectClass.prototype.className; + this._where = {}; + this._include = []; + this._select = []; + this._limit = -1; // negative limit means, do not send a limit + + this._skip = 0; + this._defaultParams = {}; + }; + /** + * Constructs a AV.Query that is the OR of the passed in queries. For + * example: + *
var compoundQuery = AV.Query.or(query1, query2, query3);+ * + * will create a compoundQuery that is an or of the query1, query2, and + * query3. + * @param {...AV.Query} var_args The list of queries to OR. + * @return {AV.Query} The query that is the OR of the passed in queries. + */ + + + AV.Query.or = function () { + var queries = _.toArray(arguments); + + var className = null; + + AV._arrayEach(queries, function (q) { + if (_.isNull(className)) { + className = q.className; + } + + if (className !== q.className) { + throw new Error('All queries must be for the same class'); + } + }); + + var query = new AV.Query(className); + + query._orQuery(queries); + + return query; + }; + /** + * Constructs a AV.Query that is the AND of the passed in queries. For + * example: + *
var compoundQuery = AV.Query.and(query1, query2, query3);+ * + * will create a compoundQuery that is an 'and' of the query1, query2, and + * query3. + * @param {...AV.Query} var_args The list of queries to AND. + * @return {AV.Query} The query that is the AND of the passed in queries. + */ + + + AV.Query.and = function () { + var queries = _.toArray(arguments); + + var className = null; + + AV._arrayEach(queries, function (q) { + if (_.isNull(className)) { + className = q.className; + } + + if (className !== q.className) { + throw new Error('All queries must be for the same class'); + } + }); + + var query = new AV.Query(className); + + query._andQuery(queries); + + return query; + }; + /** + * Retrieves a list of AVObjects that satisfy the CQL. + * CQL syntax please see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}. + * + * @param {String} cql A CQL string, see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}. + * @param {Array} pvalues An array contains placeholder values. + * @param {AuthOptions} options + * @return {Promise} A promise that is resolved with the results when + * the query completes. + */ + + + AV.Query.doCloudQuery = function (cql, pvalues, options) { + var params = { + cql: cql + }; + + if (_.isArray(pvalues)) { + params.pvalues = pvalues; + } else { + options = pvalues; + } + + var request = _request('cloudQuery', null, null, 'GET', params, options); + + return request.then(function (response) { + //query to process results. + var query = new AV.Query(response.className); + var results = (0, _map.default)(_).call(_, response.results, function (json) { + var obj = query._newObject(response); + + if (obj._finishFetch) { + obj._finishFetch(query._processResult(json), true); + } + + return obj; + }); + return { + results: results, + count: response.count, + className: response.className + }; + }); + }; + /** + * Return a query with conditions from json. + * This can be useful to send a query from server side to client side. + * @since 4.0.0 + * @param {Object} json from {@link AV.Query#toJSON} + * @return {AV.Query} + */ + + + AV.Query.fromJSON = function (_ref) { + var className = _ref.className, + where = _ref.where, + include = _ref.include, + select = _ref.select, + includeACL = _ref.includeACL, + limit = _ref.limit, + skip = _ref.skip, + order = _ref.order; + + if (typeof className !== 'string') { + throw new TypeError('Invalid Query JSON, className must be a String.'); + } + + var query = new AV.Query(className); + + _.extend(query, { + _where: where, + _include: include, + _select: select, + _includeACL: includeACL, + _limit: limit, + _skip: skip, + _order: order + }); + + return query; + }; + + AV.Query._extend = AV._extend; + + _.extend(AV.Query.prototype, + /** @lends AV.Query.prototype */ + { + //hook to iterate result. Added by dennis
+ * Some functions are only available from Cloud Code. + *
+ * + * @namespace + * @borrows AV.Captcha.request as requestCaptcha + */ + AV.Cloud = AV.Cloud || {}; + + _.extend(AV.Cloud, + /** @lends AV.Cloud */ + { + /** + * Makes a call to a cloud function. + * @param {String} name The function name. + * @param {Object} [data] The parameters to send to the cloud function. + * @param {AuthOptions} [options] + * @return {Promise} A promise that will be resolved with the result + * of the function. + */ + run: function run(name, data, options) { + return request({ + service: 'engine', + method: 'POST', + path: "/functions/".concat(name), + data: AV._encode(data, null, true), + authOptions: options + }).then(function (resp) { + return AV._decode(resp).result; + }); + }, + + /** + * Makes a call to a cloud function, you can send {AV.Object} as param or a field of param; the response + * from server will also be parsed as an {AV.Object}, array of {AV.Object}, or object includes {AV.Object} + * @param {String} name The function name. + * @param {Object} [data] The parameters to send to the cloud function. + * @param {AuthOptions} [options] + * @return {Promise} A promise that will be resolved with the result of the function. + */ + rpc: function rpc(name, data, options) { + if (_.isArray(data)) { + return _promise.default.reject(new Error("Can't pass Array as the param of rpc function in JavaScript SDK.")); + } + + return request({ + service: 'engine', + method: 'POST', + path: "/call/".concat(name), + data: AV._encodeObjectOrArray(data), + authOptions: options + }).then(function (resp) { + return AV._decode(resp).result; + }); + }, + + /** + * Make a call to request server date time. + * @return {Promise.Send a status from current signined user to other user's private status inbox.
+ * @since 0.3.0 + * @param {AV.Status} status A status object to be send to followers. + * @param {String} target The target user or user's objectId. + * @param {AuthOptions} options + * @return {Promise} A promise that is fulfilled when the send + * completes. + * @example + * // send a private status to user '52e84e47e4b0f8de283b079b' + * var status = new AVStatus('image url', 'a message'); + * AV.Status.sendPrivateStatus(status, '52e84e47e4b0f8de283b079b').then(function(){ + * //send status successfully. + * }, function(err){ + * //an error threw. + * console.dir(err); + * }); + */ + + + AV.Status.sendPrivateStatus = function (status, target) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + if (!getSessionToken(options) && !AV.User.current()) { + throw new Error('Please signin an user.'); + } + + if (!target) { + throw new Error('Invalid target user.'); + } + + var userObjectId = _.isString(target) ? target : target.id; + + if (!userObjectId) { + throw new Error('Invalid target user.'); + } + + return getUserPointer(options).then(function (currUser) { + var query = {}; + query.className = '_User'; + query.where = { + objectId: userObjectId + }; + var data = {}; + data.query = query; + status.data = status.data || {}; + status.data.source = status.data.source || currUser; + data.data = status._getDataJSON(); + data.inboxType = 'private'; + status.inboxType = 'private'; + var request = AVRequest('statuses', null, null, 'POST', data, options); + return request.then(function (response) { + status.id = response.objectId; + status.createdAt = AV._parseDate(response.createdAt); + return status; + }); + }); + }; + /** + * Count unread statuses in someone's inbox. + * @since 0.3.0 + * @param {AV.User} owner The status owner. + * @param {String} inboxType The inbox type, 'default' by default. + * @param {AuthOptions} options + * @return {Promise} A promise that is fulfilled when the count + * completes. + * @example + * AV.Status.countUnreadStatuses(AV.User.current()).then(function(response){ + * console.log(response.unread); //unread statuses number. + * console.log(response.total); //total statuses number. + * }); + */ + + + AV.Status.countUnreadStatuses = function (owner) { + var inboxType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default'; + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (!_.isString(inboxType)) options = inboxType; + + if (!getSessionToken(options) && owner == null && !AV.User.current()) { + throw new Error('Please signin an user or pass the owner objectId.'); + } + + return _promise.default.resolve(owner || getUser(options)).then(function (owner) { + var params = {}; + params.inboxType = AV._encode(inboxType); + params.owner = AV._encode(owner); + return AVRequest('subscribe/statuses/count', null, null, 'GET', params, options); + }); + }; + /** + * reset unread statuses count in someone's inbox. + * @since 2.1.0 + * @param {AV.User} owner The status owner. + * @param {String} inboxType The inbox type, 'default' by default. + * @param {AuthOptions} options + * @return {Promise} A promise that is fulfilled when the reset + * completes. + * @example + * AV.Status.resetUnreadCount(AV.User.current()).then(function(response){ + * console.log(response.unread); //unread statuses number. + * console.log(response.total); //total statuses number. + * }); + */ + + + AV.Status.resetUnreadCount = function (owner) { + var inboxType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default'; + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (!_.isString(inboxType)) options = inboxType; + + if (!getSessionToken(options) && owner == null && !AV.User.current()) { + throw new Error('Please signin an user or pass the owner objectId.'); + } + + return _promise.default.resolve(owner || getUser(options)).then(function (owner) { + var params = {}; + params.inboxType = AV._encode(inboxType); + params.owner = AV._encode(owner); + return AVRequest('subscribe/statuses/resetUnreadCount', null, null, 'POST', params, options); + }); + }; + /** + * Create a status query to find someone's published statuses. + * @since 0.3.0 + * @param {AV.User} source The status source, typically the publisher. + * @return {AV.Query} The query object for status. + * @example + * //Find current user's published statuses. + * var query = AV.Status.statusQuery(AV.User.current()); + * query.find().then(function(statuses){ + * //process statuses + * }); + */ + + + AV.Status.statusQuery = function (source) { + var query = new AV.Query('_Status'); + + if (source) { + query.equalTo('source', source); + } + + return query; + }; + /** + *AV.InboxQuery defines a query that is used to fetch somebody's inbox statuses.
+ * @class + */ + + + AV.InboxQuery = AV.Query._extend( + /** @lends AV.InboxQuery.prototype */ + { + _objectClass: AV.Status, + _sinceId: 0, + _maxId: 0, + _inboxType: 'default', + _owner: null, + _newObject: function _newObject() { + return new AV.Status(); + }, + _createRequest: function _createRequest(params, options) { + return AV.InboxQuery.__super__._createRequest.call(this, params, options, '/subscribe/statuses'); + }, + + /** + * Sets the messageId of results to skip before returning any results. + * This is useful for pagination. + * Default is zero. + * @param {Number} n the mesage id. + * @return {AV.InboxQuery} Returns the query, so you can chain this call. + */ + sinceId: function sinceId(id) { + this._sinceId = id; + return this; + }, + + /** + * Sets the maximal messageId of results。 + * This is useful for pagination. + * Default is zero that is no limition. + * @param {Number} n the mesage id. + * @return {AV.InboxQuery} Returns the query, so you can chain this call. + */ + maxId: function maxId(id) { + this._maxId = id; + return this; + }, + + /** + * Sets the owner of the querying inbox. + * @param {AV.User} owner The inbox owner. + * @return {AV.InboxQuery} Returns the query, so you can chain this call. + */ + owner: function owner(_owner) { + this._owner = _owner; + return this; + }, + + /** + * Sets the querying inbox type.default is 'default'. + * @param {String} type The inbox type. + * @return {AV.InboxQuery} Returns the query, so you can chain this call. + */ + inboxType: function inboxType(type) { + this._inboxType = type; + return this; + }, + _getParams: function _getParams() { + var params = AV.InboxQuery.__super__._getParams.call(this); + + params.owner = AV._encode(this._owner); + params.inboxType = AV._encode(this._inboxType); + params.sinceId = AV._encode(this._sinceId); + params.maxId = AV._encode(this._maxId); + return params; + } + }); + /** + * Create a inbox status query to find someone's inbox statuses. + * @since 0.3.0 + * @param {AV.User} owner The inbox's owner + * @param {String} inboxType The inbox type,'default' by default. + * @return {AV.InboxQuery} The inbox query object. + * @see AV.InboxQuery + * @example + * //Find current user's default inbox statuses. + * var query = AV.Status.inboxQuery(AV.User.current()); + * //find the statuses after the last message id + * query.sinceId(lastMessageId); + * query.find().then(function(statuses){ + * //process statuses + * }); + */ + + AV.Status.inboxQuery = function (owner, inboxType) { + var query = new AV.InboxQuery(AV.Status); + + if (owner) { + query._owner = owner; + } + + if (inboxType) { + query._inboxType = inboxType; + } + + return query; + }; +}; + +/***/ }), +/* 535 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(2); + +var _stringify = _interopRequireDefault(__webpack_require__(34)); + +var _map = _interopRequireDefault(__webpack_require__(39)); + +var _ = __webpack_require__(1); + +var AVRequest = __webpack_require__(25)._request; + +module.exports = function (AV) { + /** + * A builder to generate sort string for app searching.For example: + * @class + * @since 0.5.1 + * @example + * var builder = new AV.SearchSortBuilder(); + * builder.ascending('key1').descending('key2','max'); + * var query = new AV.SearchQuery('Player'); + * query.sortBy(builder); + * query.find().then(); + */ + AV.SearchSortBuilder = function () { + this._sortFields = []; + }; + + _.extend(AV.SearchSortBuilder.prototype, + /** @lends AV.SearchSortBuilder.prototype */ + { + _addField: function _addField(key, order, mode, missing) { + var field = {}; + field[key] = { + order: order || 'asc', + mode: mode || 'avg', + missing: '_' + (missing || 'last') + }; + + this._sortFields.push(field); + + return this; + }, + + /** + * Sorts the results in ascending order by the given key and options. + * + * @param {String} key The key to order by. + * @param {String} mode The sort mode, default is 'avg', you can choose + * 'max' or 'min' too. + * @param {String} missing The missing key behaviour, default is 'last', + * you can choose 'first' too. + * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call. + */ + ascending: function ascending(key, mode, missing) { + return this._addField(key, 'asc', mode, missing); + }, + + /** + * Sorts the results in descending order by the given key and options. + * + * @param {String} key The key to order by. + * @param {String} mode The sort mode, default is 'avg', you can choose + * 'max' or 'min' too. + * @param {String} missing The missing key behaviour, default is 'last', + * you can choose 'first' too. + * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call. + */ + descending: function descending(key, mode, missing) { + return this._addField(key, 'desc', mode, missing); + }, + + /** + * Add a proximity based constraint for finding objects with key point + * values near the point given. + * @param {String} key The key that the AV.GeoPoint is stored in. + * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used. + * @param {Object} options The other options such as mode,order, unit etc. + * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call. + */ + whereNear: function whereNear(key, point, options) { + options = options || {}; + var field = {}; + var geo = { + lat: point.latitude, + lon: point.longitude + }; + var m = { + order: options.order || 'asc', + mode: options.mode || 'avg', + unit: options.unit || 'km' + }; + m[key] = geo; + field['_geo_distance'] = m; + + this._sortFields.push(field); + + return this; + }, + + /** + * Build a sort string by configuration. + * @return {String} the sort string. + */ + build: function build() { + return (0, _stringify.default)(AV._encode(this._sortFields)); + } + }); + /** + * App searching query.Use just like AV.Query: + * + * Visit App Searching Guide + * for more details. + * @class + * @since 0.5.1 + * @example + * var query = new AV.SearchQuery('Player'); + * query.queryString('*'); + * query.find().then(function(results) { + * console.log('Found %d objects', query.hits()); + * //Process results + * }); + */ + + + AV.SearchQuery = AV.Query._extend( + /** @lends AV.SearchQuery.prototype */ + { + _sid: null, + _hits: 0, + _queryString: null, + _highlights: null, + _sortBuilder: null, + _clazz: null, + constructor: function constructor(className) { + if (className) { + this._clazz = className; + } else { + className = '__INVALID_CLASS'; + } + + AV.Query.call(this, className); + }, + _createRequest: function _createRequest(params, options) { + return AVRequest('search/select', null, null, 'GET', params || this._getParams(), options); + }, + + /** + * Sets the sid of app searching query.Default is null. + * @param {String} sid Scroll id for searching. + * @return {AV.SearchQuery} Returns the query, so you can chain this call. + */ + sid: function sid(_sid) { + this._sid = _sid; + return this; + }, + + /** + * Sets the query string of app searching. + * @param {String} q The query string. + * @return {AV.SearchQuery} Returns the query, so you can chain this call. + */ + queryString: function queryString(q) { + this._queryString = q; + return this; + }, + + /** + * Sets the highlight fields. Such as + *
+ * query.highlights('title');
+ * //or pass an array.
+ * query.highlights(['title', 'content'])
+ *
+ * @param {String|String[]} highlights a list of fields.
+ * @return {AV.SearchQuery} Returns the query, so you can chain this call.
+ */
+ highlights: function highlights(_highlights) {
+ var objects;
+
+ if (_highlights && _.isString(_highlights)) {
+ objects = _.toArray(arguments);
+ } else {
+ objects = _highlights;
+ }
+
+ this._highlights = objects;
+ return this;
+ },
+
+ /**
+ * Sets the sort builder for this query.
+ * @see AV.SearchSortBuilder
+ * @param { AV.SearchSortBuilder} builder The sort builder.
+ * @return {AV.SearchQuery} Returns the query, so you can chain this call.
+ *
+ */
+ sortBy: function sortBy(builder) {
+ this._sortBuilder = builder;
+ return this;
+ },
+
+ /**
+ * Returns the number of objects that match this query.
+ * @return {Number}
+ */
+ hits: function hits() {
+ if (!this._hits) {
+ this._hits = 0;
+ }
+
+ return this._hits;
+ },
+ _processResult: function _processResult(json) {
+ delete json['className'];
+ delete json['_app_url'];
+ delete json['_deeplink'];
+ return json;
+ },
+
+ /**
+ * Returns true when there are more documents can be retrieved by this
+ * query instance, you can call find function to get more results.
+ * @see AV.SearchQuery#find
+ * @return {Boolean}
+ */
+ hasMore: function hasMore() {
+ return !this._hitEnd;
+ },
+
+ /**
+ * Reset current query instance state(such as sid, hits etc) except params
+ * for a new searching. After resetting, hasMore() will return true.
+ */
+ reset: function reset() {
+ this._hitEnd = false;
+ this._sid = null;
+ this._hits = 0;
+ },
+
+ /**
+ * Retrieves a list of AVObjects that satisfy this query.
+ * Either options.success or options.error is called when the find
+ * completes.
+ *
+ * @see AV.Query#find
+ * @param {AuthOptions} options
+ * @return {Promise} A promise that is resolved with the results when
+ * the query completes.
+ */
+ find: function find(options) {
+ var self = this;
+
+ var request = this._createRequest(undefined, options);
+
+ return request.then(function (response) {
+ //update sid for next querying.
+ if (response.sid) {
+ self._oldSid = self._sid;
+ self._sid = response.sid;
+ } else {
+ self._sid = null;
+ self._hitEnd = true;
+ }
+
+ self._hits = response.hits || 0;
+ return (0, _map.default)(_).call(_, response.results, function (json) {
+ if (json.className) {
+ response.className = json.className;
+ }
+
+ var obj = self._newObject(response);
+
+ obj.appURL = json['_app_url'];
+
+ obj._finishFetch(self._processResult(json), true);
+
+ return obj;
+ });
+ });
+ },
+ _getParams: function _getParams() {
+ var params = AV.SearchQuery.__super__._getParams.call(this);
+
+ delete params.where;
+
+ if (this._clazz) {
+ params.clazz = this.className;
+ }
+
+ if (this._sid) {
+ params.sid = this._sid;
+ }
+
+ if (!this._queryString) {
+ throw new Error('Please set query string.');
+ } else {
+ params.q = this._queryString;
+ }
+
+ if (this._highlights) {
+ params.highlights = this._highlights.join(',');
+ }
+
+ if (this._sortBuilder && params.order) {
+ throw new Error('sort and order can not be set at same time.');
+ }
+
+ if (this._sortBuilder) {
+ params.sort = this._sortBuilder.build();
+ }
+
+ return params;
+ }
+ });
+};
+/**
+ * Sorts the results in ascending order by the given key.
+ *
+ * @method AV.SearchQuery#ascending
+ * @param {String} key The key to order by.
+ * @return {AV.SearchQuery} Returns the query, so you can chain this call.
+ */
+
+/**
+ * Also sorts the results in ascending order by the given key. The previous sort keys have
+ * precedence over this key.
+ *
+ * @method AV.SearchQuery#addAscending
+ * @param {String} key The key to order by
+ * @return {AV.SearchQuery} Returns the query so you can chain this call.
+ */
+
+/**
+ * Sorts the results in descending order by the given key.
+ *
+ * @method AV.SearchQuery#descending
+ * @param {String} key The key to order by.
+ * @return {AV.SearchQuery} Returns the query, so you can chain this call.
+ */
+
+/**
+ * Also sorts the results in descending order by the given key. The previous sort keys have
+ * precedence over this key.
+ *
+ * @method AV.SearchQuery#addDescending
+ * @param {String} key The key to order by
+ * @return {AV.SearchQuery} Returns the query so you can chain this call.
+ */
+
+/**
+ * Include nested AV.Objects for the provided key. You can use dot
+ * notation to specify which fields in the included object are also fetch.
+ * @method AV.SearchQuery#include
+ * @param {String[]} keys The name of the key to include.
+ * @return {AV.SearchQuery} Returns the query, so you can chain this call.
+ */
+
+/**
+ * Sets the number of results to skip before returning any results.
+ * This is useful for pagination.
+ * Default is to skip zero results.
+ * @method AV.SearchQuery#skip
+ * @param {Number} n the number of results to skip.
+ * @return {AV.SearchQuery} Returns the query, so you can chain this call.
+ */
+
+/**
+ * Sets the limit of the number of results to return. The default limit is
+ * 100, with a maximum of 1000 results being returned at a time.
+ * @method AV.SearchQuery#limit
+ * @param {Number} n the number of results to limit to.
+ * @return {AV.SearchQuery} Returns the query, so you can chain this call.
+ */
+
+/***/ }),
+/* 536 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+var _interopRequireDefault = __webpack_require__(2);
+
+var _promise = _interopRequireDefault(__webpack_require__(10));
+
+var _ = __webpack_require__(1);
+
+var AVError = __webpack_require__(40);
+
+var _require = __webpack_require__(25),
+ request = _require.request;
+
+module.exports = function (AV) {
+ /**
+ * 包含了使用了 LeanCloud
+ * 离线数据分析功能的函数。
+ * + * 仅在云引擎运行环境下有效。 + *
+ * @namespace + */ + AV.Insight = AV.Insight || {}; + + _.extend(AV.Insight, + /** @lends AV.Insight */ + { + /** + * 开始一个 Insight 任务。结果里将返回 Job id,你可以拿得到的 id 使用 + * AV.Insight.JobQuery 查询任务状态和结果。 + * @param {Object} jobConfig 任务配置的 JSON 对象,例如:
+ * { "sql" : "select count(*) as c,gender from _User group by gender",
+ * "saveAs": {
+ * "className" : "UserGender",
+ * "limit": 1
+ * }
+ * }
+ *
+ * sql 指定任务执行的 SQL 语句, saveAs(可选) 指定将结果保存在哪张表里,limit 最大 1000。
+ * @param {AuthOptions} [options]
+ * @return {Promise} A promise that will be resolved with the result
+ * of the function.
+ */
+ startJob: function startJob(jobConfig, options) {
+ if (!jobConfig || !jobConfig.sql) {
+ throw new Error('Please provide the sql to run the job.');
+ }
+
+ var data = {
+ jobConfig: jobConfig,
+ appId: AV.applicationId
+ };
+ return request({
+ path: '/bigquery/jobs',
+ method: 'POST',
+ data: AV._encode(data, null, true),
+ authOptions: options,
+ signKey: false
+ }).then(function (resp) {
+ return AV._decode(resp).id;
+ });
+ },
+
+ /**
+ * 监听 Insight 任务事件(未来推出独立部署的离线分析服务后开放)
+ * + * 仅在云引擎运行环境下有效。 + *
+ * @param {String} event 监听的事件,目前尚不支持。 + * @param {Function} 监听回调函数,接收 (err, id) 两个参数,err 表示错误信息, + * id 表示任务 id。接下来你可以拿这个 id 使用AV.Insight.JobQuery 查询任务状态和结果。 + * + */ + on: function on(event, cb) {} + }); + /** + * 创建一个对象,用于查询 Insight 任务状态和结果。 + * @class + * @param {String} id 任务 id + * @since 0.5.5 + */ + + + AV.Insight.JobQuery = function (id, className) { + if (!id) { + throw new Error('Please provide the job id.'); + } + + this.id = id; + this.className = className; + this._skip = 0; + this._limit = 100; + }; + + _.extend(AV.Insight.JobQuery.prototype, + /** @lends AV.Insight.JobQuery.prototype */ + { + /** + * Sets the number of results to skip before returning any results. + * This is useful for pagination. + * Default is to skip zero results. + * @param {Number} n the number of results to skip. + * @return {AV.Query} Returns the query, so you can chain this call. + */ + skip: function skip(n) { + this._skip = n; + return this; + }, + + /** + * Sets the limit of the number of results to return. The default limit is + * 100, with a maximum of 1000 results being returned at a time. + * @param {Number} n the number of results to limit to. + * @return {AV.Query} Returns the query, so you can chain this call. + */ + limit: function limit(n) { + this._limit = n; + return this; + }, + + /** + * 查询任务状态和结果,任务结果为一个 JSON 对象,包括 status 表示任务状态, totalCount 表示总数, + * results 数组表示任务结果数组,previewCount 表示可以返回的结果总数,任务的开始和截止时间 + * startTime、endTime 等信息。 + * + * @param {AuthOptions} [options] + * @return {Promise} A promise that will be resolved with the result + * of the function. + * + */ + find: function find(options) { + var params = { + skip: this._skip, + limit: this._limit + }; + return request({ + path: "/bigquery/jobs/".concat(this.id), + method: 'GET', + query: params, + authOptions: options, + signKey: false + }).then(function (response) { + if (response.error) { + return _promise.default.reject(new AVError(response.code, response.error)); + } + + return _promise.default.resolve(response); + }); + } + }); +}; + +/***/ }), +/* 537 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(2); + +var _promise = _interopRequireDefault(__webpack_require__(10)); + +var _ = __webpack_require__(1); + +var _require = __webpack_require__(25), + LCRequest = _require.request; + +var _require2 = __webpack_require__(28), + getSessionToken = _require2.getSessionToken; + +module.exports = function (AV) { + var getUserWithSessionToken = function getUserWithSessionToken(authOptions) { + if (authOptions.user) { + if (!authOptions.user._sessionToken) { + throw new Error('authOptions.user is not signed in.'); + } + + return _promise.default.resolve(authOptions.user); + } + + if (authOptions.sessionToken) { + return AV.User._fetchUserBySessionToken(authOptions.sessionToken); + } + + return AV.User.currentAsync(); + }; + + var getSessionTokenAsync = function getSessionTokenAsync(authOptions) { + var sessionToken = getSessionToken(authOptions); + + if (sessionToken) { + return _promise.default.resolve(sessionToken); + } + + return AV.User.currentAsync().then(function (user) { + if (user) { + return user.getSessionToken(); + } + }); + }; + /** + * Contains functions to deal with Friendship in LeanCloud. + * @class + */ + + + AV.Friendship = { + /** + * Request friendship. + * @since 4.8.0 + * @param {String | AV.User | Object} options if an AV.User or string is given, it will be used as the friend. + * @param {AV.User | string} options.friend The friend (or friend's objectId) to follow. + * @param {Object} [options.attributes] key-value attributes dictionary to be used as conditions of followeeQuery. + * @param {AuthOptions} [authOptions] + * @return {PromiseAn AV.Conversation is a local representation of a LeanCloud realtime's + * conversation. This class is a subclass of AV.Object, and retains the + * same functionality of an AV.Object, but also extends it with various + * conversation specific methods, like get members, creators of this conversation. + *
+ * + * @class AV.Conversation + * @param {String} name The name of the Role to create. + * @param {Object} [options] + * @param {Boolean} [options.isSystem] Set this conversation as system conversation. + * @param {Boolean} [options.isTransient] Set this conversation as transient conversation. + */ + + +module.exports = AV.Object.extend('_Conversation', +/** @lends AV.Conversation.prototype */ +{ + constructor: function constructor(name) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + AV.Object.prototype.constructor.call(this, null, null); + this.set('name', name); + + if (options.isSystem !== undefined) { + this.set('sys', options.isSystem ? true : false); + } + + if (options.isTransient !== undefined) { + this.set('tr', options.isTransient ? true : false); + } + }, + + /** + * Get current conversation's creator. + * + * @return {String} + */ + getCreator: function getCreator() { + return this.get('c'); + }, + + /** + * Get the last message's time. + * + * @return {Date} + */ + getLastMessageAt: function getLastMessageAt() { + return this.get('lm'); + }, + + /** + * Get this conversation's members + * + * @return {String[]} + */ + getMembers: function getMembers() { + return this.get('m'); + }, + + /** + * Add a member to this conversation + * + * @param {String} member + */ + addMember: function addMember(member) { + return this.add('m', member); + }, + + /** + * Get this conversation's members who set this conversation as muted. + * + * @return {String[]} + */ + getMutedMembers: function getMutedMembers() { + return this.get('mu'); + }, + + /** + * Get this conversation's name field. + * + * @return String + */ + getName: function getName() { + return this.get('name'); + }, + + /** + * Returns true if this conversation is transient conversation. + * + * @return {Boolean} + */ + isTransient: function isTransient() { + return this.get('tr'); + }, + + /** + * Returns true if this conversation is system conversation. + * + * @return {Boolean} + */ + isSystem: function isSystem() { + return this.get('sys'); + }, + + /** + * Send realtime message to this conversation, using HTTP request. + * + * @param {String} fromClient Sender's client id. + * @param {String|Object} message The message which will send to conversation. + * It could be a raw string, or an object with a `toJSON` method, like a + * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息} + * @param {Object} [options] + * @param {Boolean} [options.transient] Whether send this message as transient message or not. + * @param {String[]} [options.toClients] Ids of clients to send to. This option can be used only in system conversation. + * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容} + * @param {AuthOptions} [authOptions] + * @return {Promise} + */ + send: function send(fromClient, message) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var authOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var data = { + from_peer: fromClient, + conv_id: this.id, + transient: false, + message: serializeMessage(message) + }; + + if (options.toClients !== undefined) { + data.to_peers = options.toClients; + } + + if (options.transient !== undefined) { + data.transient = options.transient ? true : false; + } + + if (options.pushData !== undefined) { + data.push_data = options.pushData; + } + + return _request('rtm', 'messages', null, 'POST', data, authOptions); + }, + + /** + * Send realtime broadcast message to all clients, via this conversation, using HTTP request. + * + * @param {String} fromClient Sender's client id. + * @param {String|Object} message The message which will send to conversation. + * It could be a raw string, or an object with a `toJSON` method, like a + * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息}. + * @param {Object} [options] + * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容}. + * @param {Object} [options.validTill] The message will valid till this time. + * @param {AuthOptions} [authOptions] + * @return {Promise} + */ + broadcast: function broadcast(fromClient, message) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var authOptions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var data = { + from_peer: fromClient, + conv_id: this.id, + message: serializeMessage(message) + }; + + if (options.pushData !== undefined) { + data.push = options.pushData; + } + + if (options.validTill !== undefined) { + var ts = options.validTill; + + if (_.isDate(ts)) { + ts = ts.getTime(); + } + + options.valid_till = ts; + } + + return _request('rtm', 'broadcast', null, 'POST', data, authOptions); + } +}); + +/***/ }), +/* 539 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _interopRequireDefault = __webpack_require__(2); + +var _promise = _interopRequireDefault(__webpack_require__(10)); + +var _map = _interopRequireDefault(__webpack_require__(39)); + +var _concat = _interopRequireDefault(__webpack_require__(29)); + +var _ = __webpack_require__(1); + +var _require = __webpack_require__(25), + request = _require.request; + +var _require2 = __webpack_require__(28), + ensureArray = _require2.ensureArray, + parseDate = _require2.parseDate; + +var AV = __webpack_require__(59); +/** + * The version change interval for Leaderboard + * @enum + */ + + +AV.LeaderboardVersionChangeInterval = { + NEVER: 'never', + DAY: 'day', + WEEK: 'week', + MONTH: 'month' +}; +/** + * The order of the leaderboard results + * @enum + */ + +AV.LeaderboardOrder = { + ASCENDING: 'ascending', + DESCENDING: 'descending' +}; +/** + * The update strategy for Leaderboard + * @enum + */ + +AV.LeaderboardUpdateStrategy = { + /** Only keep the best statistic. If the leaderboard is in descending order, the best statistic is the highest one. */ + BETTER: 'better', + + /** Keep the last updated statistic */ + LAST: 'last', + + /** Keep the sum of all updated statistics */ + SUM: 'sum' +}; +/** + * @typedef {Object} Ranking + * @property {number} rank Starts at 0 + * @property {number} value the statistic value of this ranking + * @property {AV.User} user The user of this ranking + * @property {Statistic[]} [includedStatistics] Other statistics of the user, specified by the `includeStatistic` option of `AV.Leaderboard.getResults()` + */ + +/** + * @typedef {Object} LeaderboardArchive + * @property {string} statisticName + * @property {number} version version of the leaderboard + * @property {string} status + * @property {string} url URL for the downloadable archive + * @property {Date} activatedAt time when this version became active + * @property {Date} deactivatedAt time when this version was deactivated by a version incrementing + */ + +/** + * @class + */ + +function Statistic(_ref) { + var name = _ref.name, + value = _ref.value, + version = _ref.version; + + /** + * @type {string} + */ + this.name = name; + /** + * @type {number} + */ + + this.value = value; + /** + * @type {number?} + */ + + this.version = version; +} + +var parseStatisticData = function parseStatisticData(statisticData) { + var _AV$_decode = AV._decode(statisticData), + name = _AV$_decode.statisticName, + value = _AV$_decode.statisticValue, + version = _AV$_decode.version; + + return new Statistic({ + name: name, + value: value, + version: version + }); +}; +/** + * @class + */ + + +AV.Leaderboard = function Leaderboard(statisticName) { + /** + * @type {string} + */ + this.statisticName = statisticName; + /** + * @type {AV.LeaderboardOrder} + */ + + this.order = undefined; + /** + * @type {AV.LeaderboardUpdateStrategy} + */ + + this.updateStrategy = undefined; + /** + * @type {AV.LeaderboardVersionChangeInterval} + */ + + this.versionChangeInterval = undefined; + /** + * @type {number} + */ + + this.version = undefined; + /** + * @type {Date?} + */ + + this.nextResetAt = undefined; + /** + * @type {Date?} + */ + + this.createdAt = undefined; +}; + +var Leaderboard = AV.Leaderboard; +/** + * Create an instance of Leaderboard for the give statistic name. + * @param {string} statisticName + * @return {AV.Leaderboard} + */ + +AV.Leaderboard.createWithoutData = function (statisticName) { + return new Leaderboard(statisticName); +}; +/** + * (masterKey required) Create a new Leaderboard. + * @param {Object} options + * @param {string} options.statisticName + * @param {AV.LeaderboardOrder} options.order + * @param {AV.LeaderboardVersionChangeInterval} [options.versionChangeInterval] default to WEEK + * @param {AV.LeaderboardUpdateStrategy} [options.updateStrategy] default to BETTER + * @param {AuthOptions} [authOptions] + * @return {PromiseAvailable in Cloud Code and Node.js only.\n *
\n */\n AV.Cloud.useMasterKey = () => {\n AV._config.useMasterKey = true;\n };\n}\n\n/**\n * Call this method to set production environment variable.\n * @function AV.setProduction\n * @param {Boolean} production True is production environment,and\n * it's true by default.\n */\nAV.setProduction = production => {\n if (!isNullOrUndefined(production)) {\n AV._config.production = production ? 1 : 0;\n } else {\n // change to default value\n AV._config.production = null;\n }\n};\n\nAV._setServerURLs = (urls, disableAppRouter = true) => {\n if (typeof urls !== 'string') {\n extend(AV._config.serverURLs, urls);\n } else {\n AV._config.serverURLs = fillServerURLs(urls);\n }\n if (disableAppRouter) {\n if (AV._appRouter) {\n AV._appRouter.disable();\n } else {\n _disableAppRouter = true;\n }\n }\n};\n/**\n * Set server URLs for services.\n * @function AV.setServerURL\n * @since 4.3.0\n * @param {String|ServerURLs} urls URLs for services. if a string was given, it will be applied for all services.\n * You can also set them when initializing SDK with `options.serverURL`\n */\nAV.setServerURL = urls => AV._setServerURLs(urls);\nAV.setServerURLs = AV.setServerURL;\n\nAV.keepErrorRawMessage = value => {\n AV._sharedConfig.keepErrorRawMessage = value;\n};\n\n/**\n * Set a deadline for requests to complete.\n * Note that file upload requests are not affected.\n * @function AV.setRequestTimeout\n * @since 3.6.0\n * @param {number} ms\n */\nAV.setRequestTimeout = ms => {\n AV._config.requestTimeout = ms;\n};\n\n// backword compatible\nAV.initialize = AV.init;\n\nconst defineConfig = property =>\n Object.defineProperty(AV, property, {\n get() {\n return AV._config[property];\n },\n set(value) {\n AV._config[property] = value;\n },\n });\n\n['applicationId', 'applicationKey', 'masterKey', 'hookKey'].forEach(\n defineConfig\n);\n\n\n\n// WEBPACK FOOTER //\n// ./src/init.js","var isPrototypeOf = require('../../internals/object-is-prototype-of');\nvar method = require('../array/virtual/slice');\n\nvar ArrayPrototype = Array.prototype;\n\nmodule.exports = function (it) {\n var own = it.slice;\n return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.slice) ? method : own;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/instance/slice.js\n// module id = 383\n// module chunks = 0 1","require('../../../modules/es.array.slice');\nvar entryVirtual = require('../../../internals/entry-virtual');\n\nmodule.exports = entryVirtual('Array').slice;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/virtual/slice.js\n// module id = 384\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar isArray = require('../internals/is-array');\nvar isConstructor = require('../internals/is-constructor');\nvar isObject = require('../internals/is-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar createProperty = require('../internals/create-property');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\nvar un$Slice = require('../internals/array-slice');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('slice');\n\nvar SPECIES = wellKnownSymbol('species');\nvar $Array = Array;\nvar max = Math.max;\n\n// `Array.prototype.slice` method\n// https://tc39.es/ecma262/#sec-array.prototype.slice\n// fallback for not array-like ES3 strings and DOM objects\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {\n slice: function slice(start, end) {\n var O = toIndexedObject(this);\n var length = lengthOfArrayLike(O);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible\n var Constructor, result, n;\n if (isArray(O)) {\n Constructor = O.constructor;\n // cross-realm fallback\n if (isConstructor(Constructor) && (Constructor === $Array || isArray(Constructor.prototype))) {\n Constructor = undefined;\n } else if (isObject(Constructor)) {\n Constructor = Constructor[SPECIES];\n if (Constructor === null) Constructor = undefined;\n }\n if (Constructor === $Array || Constructor === undefined) {\n return un$Slice(O, k, fin);\n }\n }\n result = new (Constructor === undefined ? $Array : Constructor)(max(fin - k, 0));\n for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);\n result.length = n;\n return result;\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.slice.js\n// module id = 385\n// module chunks = 0 1","require('../../modules/es.object.define-property');\nvar path = require('../../internals/path');\n\nvar Object = path.Object;\n\nvar defineProperty = module.exports = function defineProperty(it, key, desc) {\n return Object.defineProperty(it, key, desc);\n};\n\nif (Object.defineProperty.sham) defineProperty.sham = true;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/object/define-property.js\n// module id = 386\n// module chunks = 0 1","var $ = require('../internals/export');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar defineProperty = require('../internals/object-define-property').f;\n\n// `Object.defineProperty` method\n// https://tc39.es/ecma262/#sec-object.defineproperty\n// eslint-disable-next-line es-x/no-object-defineproperty -- safe\n$({ target: 'Object', stat: true, forced: Object.defineProperty !== defineProperty, sham: !DESCRIPTORS }, {\n defineProperty: defineProperty\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.object.define-property.js\n// module id = 387\n// module chunks = 0 1","const ajax = require('./utils/ajax');\nconst Cache = require('./cache');\n\nfunction AppRouter(AV) {\n this.AV = AV;\n this.lockedUntil = 0;\n Cache.getAsync('serverURLs')\n .then(data => {\n if (this.disabled) return;\n if (!data) return this.lock(0);\n const { serverURLs, lockedUntil } = data;\n this.AV._setServerURLs(serverURLs, false);\n this.lockedUntil = lockedUntil;\n })\n .catch(() => this.lock(0));\n}\n\nAppRouter.prototype.disable = function disable() {\n this.disabled = true;\n};\nAppRouter.prototype.lock = function lock(ttl) {\n this.lockedUntil = Date.now() + ttl;\n};\nAppRouter.prototype.refresh = function refresh() {\n if (this.disabled) return;\n if (Date.now() < this.lockedUntil) return;\n this.lock(10);\n const url = 'https://app-router.com/2/route';\n return ajax({\n method: 'get',\n url,\n query: {\n appId: this.AV.applicationId,\n },\n })\n .then(servers => {\n if (this.disabled) return;\n let ttl = servers.ttl;\n if (!ttl) throw new Error('missing ttl');\n ttl = ttl * 1000;\n const protocal = 'https://';\n const serverURLs = {\n push: protocal + servers.push_server,\n stats: protocal + servers.stats_server,\n engine: protocal + servers.engine_server,\n api: protocal + servers.api_server,\n };\n this.AV._setServerURLs(serverURLs, false);\n this.lock(ttl);\n return Cache.setAsync(\n 'serverURLs',\n {\n serverURLs,\n lockedUntil: this.lockedUntil,\n },\n ttl\n );\n })\n .catch(error => {\n // bypass all errors\n console.warn(`refresh server URLs failed: ${error.message}`);\n this.lock(600);\n });\n};\n\nmodule.exports = AppRouter;\n\n\n\n// WEBPACK FOOTER //\n// ./src/app-router.js","module.exports = require('../../full/symbol');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/symbol/index.js\n// module id = 389\n// module chunks = 0 1","var parent = require('../../actual/symbol');\nrequire('../../modules/esnext.symbol.async-dispose');\nrequire('../../modules/esnext.symbol.dispose');\nrequire('../../modules/esnext.symbol.matcher');\nrequire('../../modules/esnext.symbol.metadata-key');\nrequire('../../modules/esnext.symbol.observable');\n// TODO: Remove from `core-js@4`\nrequire('../../modules/esnext.symbol.metadata');\nrequire('../../modules/esnext.symbol.pattern-match');\nrequire('../../modules/esnext.symbol.replace-all');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/symbol/index.js\n// module id = 390\n// module chunks = 0 1","var parent = require('../../stable/symbol');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/symbol/index.js\n// module id = 391\n// module chunks = 0 1","require('../../modules/es.array.concat');\nrequire('../../modules/es.object.to-string');\nrequire('../../modules/es.symbol');\nrequire('../../modules/es.symbol.async-iterator');\nrequire('../../modules/es.symbol.description');\nrequire('../../modules/es.symbol.has-instance');\nrequire('../../modules/es.symbol.is-concat-spreadable');\nrequire('../../modules/es.symbol.iterator');\nrequire('../../modules/es.symbol.match');\nrequire('../../modules/es.symbol.match-all');\nrequire('../../modules/es.symbol.replace');\nrequire('../../modules/es.symbol.search');\nrequire('../../modules/es.symbol.species');\nrequire('../../modules/es.symbol.split');\nrequire('../../modules/es.symbol.to-primitive');\nrequire('../../modules/es.symbol.to-string-tag');\nrequire('../../modules/es.symbol.unscopables');\nrequire('../../modules/es.json.to-string-tag');\nrequire('../../modules/es.math.to-string-tag');\nrequire('../../modules/es.reflect.to-string-tag');\nvar path = require('../../internals/path');\n\nmodule.exports = path.Symbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/symbol/index.js\n// module id = 392\n// module chunks = 0 1","// TODO: Remove this module from `core-js@4` since it's split to modules listed below\nrequire('../modules/es.symbol.constructor');\nrequire('../modules/es.symbol.for');\nrequire('../modules/es.symbol.key-for');\nrequire('../modules/es.json.stringify');\nrequire('../modules/es.object.get-own-property-symbols');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.js\n// module id = 393\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar global = require('../internals/global');\nvar call = require('../internals/function-call');\nvar uncurryThis = require('../internals/function-uncurry-this');\nvar IS_PURE = require('../internals/is-pure');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar NATIVE_SYMBOL = require('../internals/native-symbol');\nvar fails = require('../internals/fails');\nvar hasOwn = require('../internals/has-own-property');\nvar isPrototypeOf = require('../internals/object-is-prototype-of');\nvar anObject = require('../internals/an-object');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toPropertyKey = require('../internals/to-property-key');\nvar $toString = require('../internals/to-string');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar nativeObjectCreate = require('../internals/object-create');\nvar objectKeys = require('../internals/object-keys');\nvar getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');\nvar getOwnPropertyNamesExternal = require('../internals/object-get-own-property-names-external');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar definePropertyModule = require('../internals/object-define-property');\nvar definePropertiesModule = require('../internals/object-define-properties');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar defineBuiltIn = require('../internals/define-built-in');\nvar shared = require('../internals/shared');\nvar sharedKey = require('../internals/shared-key');\nvar hiddenKeys = require('../internals/hidden-keys');\nvar uid = require('../internals/uid');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar wrappedWellKnownSymbolModule = require('../internals/well-known-symbol-wrapped');\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\nvar defineSymbolToPrimitive = require('../internals/symbol-define-to-primitive');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar InternalStateModule = require('../internals/internal-state');\nvar $forEach = require('../internals/array-iteration').forEach;\n\nvar HIDDEN = sharedKey('hidden');\nvar SYMBOL = 'Symbol';\nvar PROTOTYPE = 'prototype';\n\nvar setInternalState = InternalStateModule.set;\nvar getInternalState = InternalStateModule.getterFor(SYMBOL);\n\nvar ObjectPrototype = Object[PROTOTYPE];\nvar $Symbol = global.Symbol;\nvar SymbolPrototype = $Symbol && $Symbol[PROTOTYPE];\nvar TypeError = global.TypeError;\nvar QObject = global.QObject;\nvar nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\nvar nativeDefineProperty = definePropertyModule.f;\nvar nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f;\nvar nativePropertyIsEnumerable = propertyIsEnumerableModule.f;\nvar push = uncurryThis([].push);\n\nvar AllSymbols = shared('symbols');\nvar ObjectPrototypeSymbols = shared('op-symbols');\nvar WellKnownSymbolsStore = shared('wks');\n\n// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173\nvar USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;\n\n// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\nvar setSymbolDescriptor = DESCRIPTORS && fails(function () {\n return nativeObjectCreate(nativeDefineProperty({}, 'a', {\n get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; }\n })).a != 7;\n}) ? function (O, P, Attributes) {\n var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, P);\n if (ObjectPrototypeDescriptor) delete ObjectPrototype[P];\n nativeDefineProperty(O, P, Attributes);\n if (ObjectPrototypeDescriptor && O !== ObjectPrototype) {\n nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor);\n }\n} : nativeDefineProperty;\n\nvar wrap = function (tag, description) {\n var symbol = AllSymbols[tag] = nativeObjectCreate(SymbolPrototype);\n setInternalState(symbol, {\n type: SYMBOL,\n tag: tag,\n description: description\n });\n if (!DESCRIPTORS) symbol.description = description;\n return symbol;\n};\n\nvar $defineProperty = function defineProperty(O, P, Attributes) {\n if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes);\n anObject(O);\n var key = toPropertyKey(P);\n anObject(Attributes);\n if (hasOwn(AllSymbols, key)) {\n if (!Attributes.enumerable) {\n if (!hasOwn(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, {}));\n O[HIDDEN][key] = true;\n } else {\n if (hasOwn(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;\n Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) });\n } return setSymbolDescriptor(O, key, Attributes);\n } return nativeDefineProperty(O, key, Attributes);\n};\n\nvar $defineProperties = function defineProperties(O, Properties) {\n anObject(O);\n var properties = toIndexedObject(Properties);\n var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));\n $forEach(keys, function (key) {\n if (!DESCRIPTORS || call($propertyIsEnumerable, properties, key)) $defineProperty(O, key, properties[key]);\n });\n return O;\n};\n\nvar $create = function create(O, Properties) {\n return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties);\n};\n\nvar $propertyIsEnumerable = function propertyIsEnumerable(V) {\n var P = toPropertyKey(V);\n var enumerable = call(nativePropertyIsEnumerable, this, P);\n if (this === ObjectPrototype && hasOwn(AllSymbols, P) && !hasOwn(ObjectPrototypeSymbols, P)) return false;\n return enumerable || !hasOwn(this, P) || !hasOwn(AllSymbols, P) || hasOwn(this, HIDDEN) && this[HIDDEN][P]\n ? enumerable : true;\n};\n\nvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {\n var it = toIndexedObject(O);\n var key = toPropertyKey(P);\n if (it === ObjectPrototype && hasOwn(AllSymbols, key) && !hasOwn(ObjectPrototypeSymbols, key)) return;\n var descriptor = nativeGetOwnPropertyDescriptor(it, key);\n if (descriptor && hasOwn(AllSymbols, key) && !(hasOwn(it, HIDDEN) && it[HIDDEN][key])) {\n descriptor.enumerable = true;\n }\n return descriptor;\n};\n\nvar $getOwnPropertyNames = function getOwnPropertyNames(O) {\n var names = nativeGetOwnPropertyNames(toIndexedObject(O));\n var result = [];\n $forEach(names, function (key) {\n if (!hasOwn(AllSymbols, key) && !hasOwn(hiddenKeys, key)) push(result, key);\n });\n return result;\n};\n\nvar $getOwnPropertySymbols = function (O) {\n var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;\n var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));\n var result = [];\n $forEach(names, function (key) {\n if (hasOwn(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwn(ObjectPrototype, key))) {\n push(result, AllSymbols[key]);\n }\n });\n return result;\n};\n\n// `Symbol` constructor\n// https://tc39.es/ecma262/#sec-symbol-constructor\nif (!NATIVE_SYMBOL) {\n $Symbol = function Symbol() {\n if (isPrototypeOf(SymbolPrototype, this)) throw TypeError('Symbol is not a constructor');\n var description = !arguments.length || arguments[0] === undefined ? undefined : $toString(arguments[0]);\n var tag = uid(description);\n var setter = function (value) {\n if (this === ObjectPrototype) call(setter, ObjectPrototypeSymbols, value);\n if (hasOwn(this, HIDDEN) && hasOwn(this[HIDDEN], tag)) this[HIDDEN][tag] = false;\n setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));\n };\n if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });\n return wrap(tag, description);\n };\n\n SymbolPrototype = $Symbol[PROTOTYPE];\n\n defineBuiltIn(SymbolPrototype, 'toString', function toString() {\n return getInternalState(this).tag;\n });\n\n defineBuiltIn($Symbol, 'withoutSetter', function (description) {\n return wrap(uid(description), description);\n });\n\n propertyIsEnumerableModule.f = $propertyIsEnumerable;\n definePropertyModule.f = $defineProperty;\n definePropertiesModule.f = $defineProperties;\n getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor;\n getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames;\n getOwnPropertySymbolsModule.f = $getOwnPropertySymbols;\n\n wrappedWellKnownSymbolModule.f = function (name) {\n return wrap(wellKnownSymbol(name), name);\n };\n\n if (DESCRIPTORS) {\n // https://github.com/tc39/proposal-Symbol-description\n nativeDefineProperty(SymbolPrototype, 'description', {\n configurable: true,\n get: function description() {\n return getInternalState(this).description;\n }\n });\n if (!IS_PURE) {\n defineBuiltIn(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });\n }\n }\n}\n\n$({ global: true, constructor: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, {\n Symbol: $Symbol\n});\n\n$forEach(objectKeys(WellKnownSymbolsStore), function (name) {\n defineWellKnownSymbol(name);\n});\n\n$({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, {\n useSetter: function () { USE_SETTER = true; },\n useSimple: function () { USE_SETTER = false; }\n});\n\n$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, {\n // `Object.create` method\n // https://tc39.es/ecma262/#sec-object.create\n create: $create,\n // `Object.defineProperty` method\n // https://tc39.es/ecma262/#sec-object.defineproperty\n defineProperty: $defineProperty,\n // `Object.defineProperties` method\n // https://tc39.es/ecma262/#sec-object.defineproperties\n defineProperties: $defineProperties,\n // `Object.getOwnPropertyDescriptor` method\n // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors\n getOwnPropertyDescriptor: $getOwnPropertyDescriptor\n});\n\n$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, {\n // `Object.getOwnPropertyNames` method\n // https://tc39.es/ecma262/#sec-object.getownpropertynames\n getOwnPropertyNames: $getOwnPropertyNames\n});\n\n// `Symbol.prototype[@@toPrimitive]` method\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive\ndefineSymbolToPrimitive();\n\n// `Symbol.prototype[@@toStringTag]` property\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag\nsetToStringTag($Symbol, SYMBOL);\n\nhiddenKeys[HIDDEN] = true;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.constructor.js\n// module id = 394\n// module chunks = 0 1","/* eslint-disable es-x/no-object-getownpropertynames -- safe */\nvar classof = require('../internals/classof-raw');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar $getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar arraySlice = require('../internals/array-slice-simple');\n\nvar windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames\n ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function (it) {\n try {\n return $getOwnPropertyNames(it);\n } catch (error) {\n return arraySlice(windowNames);\n }\n};\n\n// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nmodule.exports.f = function getOwnPropertyNames(it) {\n return windowNames && classof(it) == 'Window'\n ? getWindowNames(it)\n : $getOwnPropertyNames(toIndexedObject(it));\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/internals/object-get-own-property-names-external.js\n// module id = 395\n// module chunks = 0 1","var toAbsoluteIndex = require('../internals/to-absolute-index');\nvar lengthOfArrayLike = require('../internals/length-of-array-like');\nvar createProperty = require('../internals/create-property');\n\nvar $Array = Array;\nvar max = Math.max;\n\nmodule.exports = function (O, start, end) {\n var length = lengthOfArrayLike(O);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n var result = $Array(max(fin - k, 0));\n for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]);\n result.length = n;\n return result;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/internals/array-slice-simple.js\n// module id = 396\n// module chunks = 0 1","var $ = require('../internals/export');\nvar getBuiltIn = require('../internals/get-built-in');\nvar hasOwn = require('../internals/has-own-property');\nvar toString = require('../internals/to-string');\nvar shared = require('../internals/shared');\nvar NATIVE_SYMBOL_REGISTRY = require('../internals/native-symbol-registry');\n\nvar StringToSymbolRegistry = shared('string-to-symbol-registry');\nvar SymbolToStringRegistry = shared('symbol-to-string-registry');\n\n// `Symbol.for` method\n// https://tc39.es/ecma262/#sec-symbol.for\n$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, {\n 'for': function (key) {\n var string = toString(key);\n if (hasOwn(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];\n var symbol = getBuiltIn('Symbol')(string);\n StringToSymbolRegistry[string] = symbol;\n SymbolToStringRegistry[symbol] = string;\n return symbol;\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.for.js\n// module id = 397\n// module chunks = 0 1","var $ = require('../internals/export');\nvar hasOwn = require('../internals/has-own-property');\nvar isSymbol = require('../internals/is-symbol');\nvar tryToString = require('../internals/try-to-string');\nvar shared = require('../internals/shared');\nvar NATIVE_SYMBOL_REGISTRY = require('../internals/native-symbol-registry');\n\nvar SymbolToStringRegistry = shared('symbol-to-string-registry');\n\n// `Symbol.keyFor` method\n// https://tc39.es/ecma262/#sec-symbol.keyfor\n$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, {\n keyFor: function keyFor(sym) {\n if (!isSymbol(sym)) throw TypeError(tryToString(sym) + ' is not a symbol');\n if (hasOwn(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.key-for.js\n// module id = 398\n// module chunks = 0 1","var $ = require('../internals/export');\nvar NATIVE_SYMBOL = require('../internals/native-symbol');\nvar fails = require('../internals/fails');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar toObject = require('../internals/to-object');\n\n// V8 ~ Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives\n// https://bugs.chromium.org/p/v8/issues/detail?id=3443\nvar FORCED = !NATIVE_SYMBOL || fails(function () { getOwnPropertySymbolsModule.f(1); });\n\n// `Object.getOwnPropertySymbols` method\n// https://tc39.es/ecma262/#sec-object.getownpropertysymbols\n$({ target: 'Object', stat: true, forced: FORCED }, {\n getOwnPropertySymbols: function getOwnPropertySymbols(it) {\n var $getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return $getOwnPropertySymbols ? $getOwnPropertySymbols(toObject(it)) : [];\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.object.get-own-property-symbols.js\n// module id = 399\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.asyncIterator` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.asynciterator\ndefineWellKnownSymbol('asyncIterator');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.async-iterator.js\n// module id = 400\n// module chunks = 0 1","// empty\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.description.js\n// module id = 401\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.hasInstance` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.hasinstance\ndefineWellKnownSymbol('hasInstance');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.has-instance.js\n// module id = 402\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.isConcatSpreadable` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.isconcatspreadable\ndefineWellKnownSymbol('isConcatSpreadable');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.is-concat-spreadable.js\n// module id = 403\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.match` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.match\ndefineWellKnownSymbol('match');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.match.js\n// module id = 404\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.matchAll` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.matchall\ndefineWellKnownSymbol('matchAll');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.match-all.js\n// module id = 405\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.replace` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.replace\ndefineWellKnownSymbol('replace');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.replace.js\n// module id = 406\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.search` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.search\ndefineWellKnownSymbol('search');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.search.js\n// module id = 407\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.species` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.species\ndefineWellKnownSymbol('species');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.species.js\n// module id = 408\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.split` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.split\ndefineWellKnownSymbol('split');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.split.js\n// module id = 409\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\nvar defineSymbolToPrimitive = require('../internals/symbol-define-to-primitive');\n\n// `Symbol.toPrimitive` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.toprimitive\ndefineWellKnownSymbol('toPrimitive');\n\n// `Symbol.prototype[@@toPrimitive]` method\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive\ndefineSymbolToPrimitive();\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.to-primitive.js\n// module id = 410\n// module chunks = 0 1","var getBuiltIn = require('../internals/get-built-in');\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\nvar setToStringTag = require('../internals/set-to-string-tag');\n\n// `Symbol.toStringTag` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.tostringtag\ndefineWellKnownSymbol('toStringTag');\n\n// `Symbol.prototype[@@toStringTag]` property\n// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag\nsetToStringTag(getBuiltIn('Symbol'), 'Symbol');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.to-string-tag.js\n// module id = 411\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.unscopables` well-known symbol\n// https://tc39.es/ecma262/#sec-symbol.unscopables\ndefineWellKnownSymbol('unscopables');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.symbol.unscopables.js\n// module id = 412\n// module chunks = 0 1","var global = require('../internals/global');\nvar setToStringTag = require('../internals/set-to-string-tag');\n\n// JSON[@@toStringTag] property\n// https://tc39.es/ecma262/#sec-json-@@tostringtag\nsetToStringTag(global.JSON, 'JSON', true);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.json.to-string-tag.js\n// module id = 413\n// module chunks = 0 1","// empty\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.math.to-string-tag.js\n// module id = 414\n// module chunks = 0 1","// empty\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.reflect.to-string-tag.js\n// module id = 415\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.asyncDispose` well-known symbol\n// https://github.com/tc39/proposal-using-statement\ndefineWellKnownSymbol('asyncDispose');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.async-dispose.js\n// module id = 416\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.dispose` well-known symbol\n// https://github.com/tc39/proposal-using-statement\ndefineWellKnownSymbol('dispose');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.dispose.js\n// module id = 417\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.matcher` well-known symbol\n// https://github.com/tc39/proposal-pattern-matching\ndefineWellKnownSymbol('matcher');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.matcher.js\n// module id = 418\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.metadataKey` well-known symbol\n// https://github.com/tc39/proposal-decorator-metadata\ndefineWellKnownSymbol('metadataKey');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.metadata-key.js\n// module id = 419\n// module chunks = 0 1","var defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.observable` well-known symbol\n// https://github.com/tc39/proposal-observable\ndefineWellKnownSymbol('observable');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.observable.js\n// module id = 420\n// module chunks = 0 1","// TODO: Remove from `core-js@4`\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.metadata` well-known symbol\n// https://github.com/tc39/proposal-decorators\ndefineWellKnownSymbol('metadata');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.metadata.js\n// module id = 421\n// module chunks = 0 1","// TODO: remove from `core-js@4`\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\n// `Symbol.patternMatch` well-known symbol\n// https://github.com/tc39/proposal-pattern-matching\ndefineWellKnownSymbol('patternMatch');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.pattern-match.js\n// module id = 422\n// module chunks = 0 1","// TODO: remove from `core-js@4`\nvar defineWellKnownSymbol = require('../internals/define-well-known-symbol');\n\ndefineWellKnownSymbol('replaceAll');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/esnext.symbol.replace-all.js\n// module id = 423\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/symbol/iterator\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/symbol/iterator.js\n// module id = 424\n// module chunks = 0 1","module.exports = require('../../full/symbol/iterator');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/symbol/iterator.js\n// module id = 425\n// module chunks = 0 1","var parent = require('../../actual/symbol/iterator');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/symbol/iterator.js\n// module id = 426\n// module chunks = 0 1","var parent = require('../../stable/symbol/iterator');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/symbol/iterator.js\n// module id = 427\n// module chunks = 0 1","var parent = require('../../es/symbol/iterator');\nrequire('../../modules/web.dom-collections.iterator');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/symbol/iterator.js\n// module id = 428\n// module chunks = 0 1","require('../../modules/es.array.iterator');\nrequire('../../modules/es.object.to-string');\nrequire('../../modules/es.string.iterator');\nrequire('../../modules/es.symbol.iterator');\nvar WrappedWellKnownSymbolModule = require('../../internals/well-known-symbol-wrapped');\n\nmodule.exports = WrappedWellKnownSymbolModule.f('iterator');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/symbol/iterator.js\n// module id = 429\n// module chunks = 0 1","module.exports = require(\"core-js-pure/stable/instance/filter\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js-stable/instance/filter.js\n// module id = 430\n// module chunks = 0 1","var parent = require('../../es/instance/filter');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/instance/filter.js\n// module id = 431\n// module chunks = 0 1","var isPrototypeOf = require('../../internals/object-is-prototype-of');\nvar method = require('../array/virtual/filter');\n\nvar ArrayPrototype = Array.prototype;\n\nmodule.exports = function (it) {\n var own = it.filter;\n return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.filter) ? method : own;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/instance/filter.js\n// module id = 432\n// module chunks = 0 1","require('../../../modules/es.array.filter');\nvar entryVirtual = require('../../../internals/entry-virtual');\n\nmodule.exports = entryVirtual('Array').filter;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/virtual/filter.js\n// module id = 433\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar $filter = require('../internals/array-iteration').filter;\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter');\n\n// `Array.prototype.filter` method\n// https://tc39.es/ecma262/#sec-array.prototype.filter\n// with adding support of @@species\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {\n filter: function filter(callbackfn /* , thisArg */) {\n return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.filter.js\n// module id = 434\n// module chunks = 0 1","// Copyright (c) 2015-2017 David M. Lee, II\n'use strict';\n\n/**\n * Local reference to TimeoutError\n * @private\n */\nvar TimeoutError;\n\n/**\n * Rejects a promise with a {@link TimeoutError} if it does not settle within\n * the specified timeout.\n *\n * @param {Promise} promise The promise.\n * @param {number} timeoutMillis Number of milliseconds to wait on settling.\n * @returns {Promise} Either resolves/rejects with `promise`, or rejects with\n * `TimeoutError`, whichever settles first.\n */\nvar timeout = module.exports.timeout = function(promise, timeoutMillis) {\n var error = new TimeoutError(),\n timeout;\n\n return Promise.race([\n promise,\n new Promise(function(resolve, reject) {\n timeout = setTimeout(function() {\n reject(error);\n }, timeoutMillis);\n }),\n ]).then(function(v) {\n clearTimeout(timeout);\n return v;\n }, function(err) {\n clearTimeout(timeout);\n throw err;\n });\n};\n\n/**\n * Exception indicating that the timeout expired.\n */\nTimeoutError = module.exports.TimeoutError = function() {\n Error.call(this)\n this.stack = Error().stack\n this.message = 'Timeout';\n};\n\nTimeoutError.prototype = Object.create(Error.prototype);\nTimeoutError.prototype.name = \"TimeoutError\";\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/promise-timeout/index.js\n// module id = 435\n// module chunks = 0 1","var _ = require('underscore');\n\nmodule.exports = function(AV) {\n var eventSplitter = /\\s+/;\n var slice = Array.prototype.slice;\n\n /**\n * @class\n *\n *AV.Events is a fork of Backbone's Events module, provided for your\n * convenience.
\n *\n *A module that can be mixed in to any object in order to provide\n * it with custom events. You may bind callback functions to an event\n * with `on`, or remove these functions with `off`.\n * Triggering an event fires all callbacks in the order that `on` was\n * called.\n *\n * @private\n * @example\n * var object = {};\n * _.extend(object, AV.Events);\n * object.on('expand', function(){ alert('expanded'); });\n * object.trigger('expand');
\n *\n */\n AV.Events = {\n /**\n * Bind one or more space separated events, `events`, to a `callback`\n * function. Passing `\"all\"` will bind the callback to all events fired.\n */\n on: function(events, callback, context) {\n var calls, event, node, tail, list;\n if (!callback) {\n return this;\n }\n events = events.split(eventSplitter);\n calls = this._callbacks || (this._callbacks = {});\n\n // Create an immutable callback list, allowing traversal during\n // modification. The tail is an empty object that will always be used\n // as the next node.\n event = events.shift();\n while (event) {\n list = calls[event];\n node = list ? list.tail : {};\n node.next = tail = {};\n node.context = context;\n node.callback = callback;\n calls[event] = { tail: tail, next: list ? list.next : node };\n event = events.shift();\n }\n\n return this;\n },\n\n /**\n * Remove one or many callbacks. If `context` is null, removes all callbacks\n * with that function. If `callback` is null, removes all callbacks for the\n * event. If `events` is null, removes all bound callbacks for all events.\n */\n off: function(events, callback, context) {\n var event, calls, node, tail, cb, ctx;\n\n // No events, or removing *all* events.\n if (!(calls = this._callbacks)) {\n return;\n }\n if (!(events || callback || context)) {\n delete this._callbacks;\n return this;\n }\n\n // Loop through the listed events and contexts, splicing them out of the\n // linked list of callbacks if appropriate.\n events = events ? events.split(eventSplitter) : _.keys(calls);\n event = events.shift();\n while (event) {\n node = calls[event];\n delete calls[event];\n if (!node || !(callback || context)) {\n continue;\n }\n // Create a new list, omitting the indicated callbacks.\n tail = node.tail;\n node = node.next;\n while (node !== tail) {\n cb = node.callback;\n ctx = node.context;\n if ((callback && cb !== callback) || (context && ctx !== context)) {\n this.on(event, cb, ctx);\n }\n node = node.next;\n }\n event = events.shift();\n }\n\n return this;\n },\n\n /**\n * Trigger one or many events, firing all bound callbacks. Callbacks are\n * passed the same arguments as `trigger` is, apart from the event name\n * (unless you're listening on `\"all\"`, which will cause your callback to\n * receive the true name of the event as the first argument).\n */\n trigger: function(events) {\n var event, node, calls, tail, args, all, rest;\n if (!(calls = this._callbacks)) {\n return this;\n }\n all = calls.all;\n events = events.split(eventSplitter);\n rest = slice.call(arguments, 1);\n\n // For each event, walk through the linked list of callbacks twice,\n // first to trigger the event, then to trigger any `\"all\"` callbacks.\n event = events.shift();\n while (event) {\n node = calls[event];\n if (node) {\n tail = node.tail;\n while ((node = node.next) !== tail) {\n node.callback.apply(node.context || this, rest);\n }\n }\n node = all;\n if (node) {\n tail = node.tail;\n args = [event].concat(rest);\n while ((node = node.next) !== tail) {\n node.callback.apply(node.context || this, args);\n }\n }\n event = events.shift();\n }\n\n return this;\n },\n };\n\n /**\n * @function\n */\n AV.Events.bind = AV.Events.on;\n\n /**\n * @function\n */\n AV.Events.unbind = AV.Events.off;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/event.js","var _ = require('underscore');\n\n/*global navigator: false */\nmodule.exports = function(AV) {\n /**\n * Creates a new GeoPoint with any of the following forms:Represents a latitude / longitude point that may be associated\n * with a key in a AVObject or used as a reference point for geo queries.\n * This allows proximity-based queries on the key.
\n *\n *Only one key in a class may contain a GeoPoint.
\n *\n *Example:
\n * var point = new AV.GeoPoint(30.0, -20.0);\n * var object = new AV.Object(\"PlaceObject\");\n * object.set(\"location\", point);\n * object.save();\n */\n AV.GeoPoint = function(arg1, arg2) {\n if (_.isArray(arg1)) {\n AV.GeoPoint._validate(arg1[0], arg1[1]);\n this.latitude = arg1[0];\n this.longitude = arg1[1];\n } else if (_.isObject(arg1)) {\n AV.GeoPoint._validate(arg1.latitude, arg1.longitude);\n this.latitude = arg1.latitude;\n this.longitude = arg1.longitude;\n } else if (_.isNumber(arg1) && _.isNumber(arg2)) {\n AV.GeoPoint._validate(arg1, arg2);\n this.latitude = arg1;\n this.longitude = arg2;\n } else {\n this.latitude = 0;\n this.longitude = 0;\n }\n\n // Add properties so that anyone using Webkit or Mozilla will get an error\n // if they try to set values that are out of bounds.\n var self = this;\n if (this.__defineGetter__ && this.__defineSetter__) {\n // Use _latitude and _longitude to actually store the values, and add\n // getters and setters for latitude and longitude.\n this._latitude = this.latitude;\n this._longitude = this.longitude;\n this.__defineGetter__('latitude', function() {\n return self._latitude;\n });\n this.__defineGetter__('longitude', function() {\n return self._longitude;\n });\n this.__defineSetter__('latitude', function(val) {\n AV.GeoPoint._validate(val, self.longitude);\n self._latitude = val;\n });\n this.__defineSetter__('longitude', function(val) {\n AV.GeoPoint._validate(self.latitude, val);\n self._longitude = val;\n });\n }\n };\n\n /**\n * @lends AV.GeoPoint.prototype\n * @property {float} latitude North-south portion of the coordinate, in range\n * [-90, 90]. Throws an exception if set out of range in a modern browser.\n * @property {float} longitude East-west portion of the coordinate, in range\n * [-180, 180]. Throws if set out of range in a modern browser.\n */\n\n /**\n * Throws an exception if the given lat-long is out of bounds.\n * @private\n */\n AV.GeoPoint._validate = function(latitude, longitude) {\n if (latitude < -90.0) {\n throw new Error('AV.GeoPoint latitude ' + latitude + ' < -90.0.');\n }\n if (latitude > 90.0) {\n throw new Error('AV.GeoPoint latitude ' + latitude + ' > 90.0.');\n }\n if (longitude < -180.0) {\n throw new Error('AV.GeoPoint longitude ' + longitude + ' < -180.0.');\n }\n if (longitude > 180.0) {\n throw new Error('AV.GeoPoint longitude ' + longitude + ' > 180.0.');\n }\n };\n\n /**\n * Creates a GeoPoint with the user's current location, if available.\n * @return {Promise.
An ACL, or Access Control List can be added to any\n * AV.Object
to restrict access to only a subset of users\n * of your application.
object.set(\"foo\", \"bar\")
\n * is an example of a AV.Op.Set. Calling object.unset(\"foo\")
\n * is a AV.Op.Unset. These operations are stored in a AV.Object and\n * sent to the server as part of object.save()
operations.\n * Instances of AV.Op should be immutable.\n *\n * You should not create subclasses of AV.Op or instantiate AV.Op\n * directly.\n */\n AV.Op = function() {\n this._initialize.apply(this, arguments);\n };\n\n _.extend(\n AV.Op.prototype,\n /** @lends AV.Op.prototype */ {\n _initialize: function() {},\n }\n );\n\n _.extend(AV.Op, {\n /**\n * To create a new Op, call AV.Op._extend();\n * @private\n */\n _extend: AV._extend,\n\n // A map of __op string to decoder function.\n _opDecoderMap: {},\n\n /**\n * Registers a function to convert a json object with an __op field into an\n * instance of a subclass of AV.Op.\n * @private\n */\n _registerDecoder: function(opName, decoder) {\n AV.Op._opDecoderMap[opName] = decoder;\n },\n\n /**\n * Converts a json object into an instance of a subclass of AV.Op.\n * @private\n */\n _decode: function(json) {\n var decoder = AV.Op._opDecoderMap[json.__op];\n if (decoder) {\n return decoder(json);\n } else {\n return undefined;\n }\n },\n });\n\n /*\n * Add a handler for Batch ops.\n */\n AV.Op._registerDecoder('Batch', function(json) {\n var op = null;\n AV._arrayEach(json.ops, function(nextOp) {\n nextOp = AV.Op._decode(nextOp);\n op = nextOp._mergeWithPrevious(op);\n });\n return op;\n });\n\n /**\n * @private\n * @class\n * A Set operation indicates that either the field was changed using\n * AV.Object.set, or it is a mutable container that was detected as being\n * changed.\n */\n AV.Op.Set = AV.Op._extend(\n /** @lends AV.Op.Set.prototype */ {\n _initialize: function(value) {\n this._value = value;\n },\n\n /**\n * Returns the new value of this field after the set.\n */\n value: function() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return AV._encode(this.value());\n },\n\n _mergeWithPrevious: function(previous) {\n return this;\n },\n\n _estimate: function(oldValue) {\n return this.value();\n },\n }\n );\n\n /**\n * A sentinel value that is returned by AV.Op.Unset._estimate to\n * indicate the field should be deleted. Basically, if you find _UNSET as a\n * value in your object, you should remove that key.\n */\n AV.Op._UNSET = {};\n\n /**\n * @private\n * @class\n * An Unset operation indicates that this field has been deleted from the\n * object.\n */\n AV.Op.Unset = AV.Op._extend(\n /** @lends AV.Op.Unset.prototype */ {\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Delete' };\n },\n\n _mergeWithPrevious: function(previous) {\n return this;\n },\n\n _estimate: function(oldValue) {\n return AV.Op._UNSET;\n },\n }\n );\n\n AV.Op._registerDecoder('Delete', function(json) {\n return new AV.Op.Unset();\n });\n\n /**\n * @private\n * @class\n * An Increment is an atomic operation where the numeric value for the field\n * will be increased by a given amount.\n */\n AV.Op.Increment = AV.Op._extend(\n /** @lends AV.Op.Increment.prototype */ {\n _initialize: function(amount) {\n this._amount = amount;\n },\n\n /**\n * Returns the amount to increment by.\n * @return {Number} the amount to increment by.\n */\n amount: function() {\n return this._amount;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Increment', amount: this._amount };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.amount());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() + this.amount());\n } else if (previous instanceof AV.Op.Increment) {\n return new AV.Op.Increment(this.amount() + previous.amount());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return this.amount();\n }\n return oldValue + this.amount();\n },\n }\n );\n\n AV.Op._registerDecoder('Increment', function(json) {\n return new AV.Op.Increment(json.amount);\n });\n\n /**\n * @private\n * @class\n * BitAnd is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n AV.Op.BitAnd = AV.Op._extend(\n /** @lends AV.Op.BitAnd.prototype */ {\n _initialize(value) {\n this._value = value;\n },\n\n value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON() {\n return { __op: 'BitAnd', value: this.value() };\n },\n\n _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(0);\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() & this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate(oldValue) {\n return oldValue & this.value();\n },\n }\n );\n\n AV.Op._registerDecoder('BitAnd', function(json) {\n return new AV.Op.BitAnd(json.value);\n });\n\n /**\n * @private\n * @class\n * BitOr is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n AV.Op.BitOr = AV.Op._extend(\n /** @lends AV.Op.BitOr.prototype */ {\n _initialize(value) {\n this._value = value;\n },\n\n value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON() {\n return { __op: 'BitOr', value: this.value() };\n },\n\n _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.value());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() | this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate(oldValue) {\n return oldValue | this.value();\n },\n }\n );\n\n AV.Op._registerDecoder('BitOr', function(json) {\n return new AV.Op.BitOr(json.value);\n });\n\n /**\n * @private\n * @class\n * BitXor is an atomic operation where the given value will be bit and to the\n * value than is stored in this field.\n */\n AV.Op.BitXor = AV.Op._extend(\n /** @lends AV.Op.BitXor.prototype */ {\n _initialize(value) {\n this._value = value;\n },\n\n value() {\n return this._value;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON() {\n return { __op: 'BitXor', value: this.value() };\n },\n\n _mergeWithPrevious(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.value());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(previous.value() ^ this.value());\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate(oldValue) {\n return oldValue ^ this.value();\n },\n }\n );\n\n AV.Op._registerDecoder('BitXor', function(json) {\n return new AV.Op.BitXor(json.value);\n });\n\n /**\n * @private\n * @class\n * Add is an atomic operation where the given objects will be appended to the\n * array that is stored in this field.\n */\n AV.Op.Add = AV.Op._extend(\n /** @lends AV.Op.Add.prototype */ {\n _initialize: function(objects) {\n this._objects = objects;\n },\n\n /**\n * Returns the objects to be added to the array.\n * @return {Array} The objects to be added to the array.\n */\n objects: function() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Add', objects: AV._encode(this.objects()) };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.objects());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.Add) {\n return new AV.Op.Add(previous.objects().concat(this.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return _.clone(this.objects());\n } else {\n return oldValue.concat(this.objects());\n }\n },\n }\n );\n\n AV.Op._registerDecoder('Add', function(json) {\n return new AV.Op.Add(AV._decode(json.objects));\n });\n\n /**\n * @private\n * @class\n * AddUnique is an atomic operation where the given items will be appended to\n * the array that is stored in this field only if they were not already\n * present in the array.\n */\n AV.Op.AddUnique = AV.Op._extend(\n /** @lends AV.Op.AddUnique.prototype */ {\n _initialize: function(objects) {\n this._objects = _.uniq(objects);\n },\n\n /**\n * Returns the objects to be added to the array.\n * @return {Array} The objects to be added to the array.\n */\n objects: function() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'AddUnique', objects: AV._encode(this.objects()) };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return new AV.Op.Set(this.objects());\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.AddUnique) {\n return new AV.Op.AddUnique(this._estimate(previous.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return _.clone(this.objects());\n } else {\n // We can't just take the _.uniq(_.union(...)) of oldValue and\n // this.objects, because the uniqueness may not apply to oldValue\n // (especially if the oldValue was set via .set())\n var newValue = _.clone(oldValue);\n AV._arrayEach(this.objects(), function(obj) {\n if (obj instanceof AV.Object && obj.id) {\n var matchingObj = _.find(newValue, function(anObj) {\n return anObj instanceof AV.Object && anObj.id === obj.id;\n });\n if (!matchingObj) {\n newValue.push(obj);\n } else {\n var index = _.indexOf(newValue, matchingObj);\n newValue[index] = obj;\n }\n } else if (!_.contains(newValue, obj)) {\n newValue.push(obj);\n }\n });\n return newValue;\n }\n },\n }\n );\n\n AV.Op._registerDecoder('AddUnique', function(json) {\n return new AV.Op.AddUnique(AV._decode(json.objects));\n });\n\n /**\n * @private\n * @class\n * Remove is an atomic operation where the given objects will be removed from\n * the array that is stored in this field.\n */\n AV.Op.Remove = AV.Op._extend(\n /** @lends AV.Op.Remove.prototype */ {\n _initialize: function(objects) {\n this._objects = _.uniq(objects);\n },\n\n /**\n * Returns the objects to be removed from the array.\n * @return {Array} The objects to be removed from the array.\n */\n objects: function() {\n return this._objects;\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n return { __op: 'Remove', objects: AV._encode(this.objects()) };\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n return previous;\n } else if (previous instanceof AV.Op.Set) {\n return new AV.Op.Set(this._estimate(previous.value()));\n } else if (previous instanceof AV.Op.Remove) {\n return new AV.Op.Remove(_.union(previous.objects(), this.objects()));\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue) {\n if (!oldValue) {\n return [];\n } else {\n var newValue = _.difference(oldValue, this.objects());\n // If there are saved AV Objects being removed, also remove them.\n AV._arrayEach(this.objects(), function(obj) {\n if (obj instanceof AV.Object && obj.id) {\n newValue = _.reject(newValue, function(other) {\n return other instanceof AV.Object && other.id === obj.id;\n });\n }\n });\n return newValue;\n }\n },\n }\n );\n\n AV.Op._registerDecoder('Remove', function(json) {\n return new AV.Op.Remove(AV._decode(json.objects));\n });\n\n /**\n * @private\n * @class\n * A Relation operation indicates that the field is an instance of\n * AV.Relation, and objects are being added to, or removed from, that\n * relation.\n */\n AV.Op.Relation = AV.Op._extend(\n /** @lends AV.Op.Relation.prototype */ {\n _initialize: function(adds, removes) {\n this._targetClassName = null;\n\n var self = this;\n\n var pointerToId = function(object) {\n if (object instanceof AV.Object) {\n if (!object.id) {\n throw new Error(\n \"You can't add an unsaved AV.Object to a relation.\"\n );\n }\n if (!self._targetClassName) {\n self._targetClassName = object.className;\n }\n if (self._targetClassName !== object.className) {\n throw new Error(\n 'Tried to create a AV.Relation with 2 different types: ' +\n self._targetClassName +\n ' and ' +\n object.className +\n '.'\n );\n }\n return object.id;\n }\n return object;\n };\n\n this.relationsToAdd = _.uniq(_.map(adds, pointerToId));\n this.relationsToRemove = _.uniq(_.map(removes, pointerToId));\n },\n\n /**\n * Returns an array of unfetched AV.Object that are being added to the\n * relation.\n * @return {Array}\n */\n added: function() {\n var self = this;\n return _.map(this.relationsToAdd, function(objectId) {\n var object = AV.Object._create(self._targetClassName);\n object.id = objectId;\n return object;\n });\n },\n\n /**\n * Returns an array of unfetched AV.Object that are being removed from\n * the relation.\n * @return {Array}\n */\n removed: function() {\n var self = this;\n return _.map(this.relationsToRemove, function(objectId) {\n var object = AV.Object._create(self._targetClassName);\n object.id = objectId;\n return object;\n });\n },\n\n /**\n * Returns a JSON version of the operation suitable for sending to AV.\n * @return {Object}\n */\n toJSON: function() {\n var adds = null;\n var removes = null;\n var self = this;\n var idToPointer = function(id) {\n return {\n __type: 'Pointer',\n className: self._targetClassName,\n objectId: id,\n };\n };\n var pointers = null;\n if (this.relationsToAdd.length > 0) {\n pointers = _.map(this.relationsToAdd, idToPointer);\n adds = { __op: 'AddRelation', objects: pointers };\n }\n\n if (this.relationsToRemove.length > 0) {\n pointers = _.map(this.relationsToRemove, idToPointer);\n removes = { __op: 'RemoveRelation', objects: pointers };\n }\n\n if (adds && removes) {\n return { __op: 'Batch', ops: [adds, removes] };\n }\n\n return adds || removes || {};\n },\n\n _mergeWithPrevious: function(previous) {\n if (!previous) {\n return this;\n } else if (previous instanceof AV.Op.Unset) {\n throw new Error(\"You can't modify a relation after deleting it.\");\n } else if (previous instanceof AV.Op.Relation) {\n if (\n previous._targetClassName &&\n previous._targetClassName !== this._targetClassName\n ) {\n throw new Error(\n 'Related object must be of class ' +\n previous._targetClassName +\n ', but ' +\n this._targetClassName +\n ' was passed in.'\n );\n }\n var newAdd = _.union(\n _.difference(previous.relationsToAdd, this.relationsToRemove),\n this.relationsToAdd\n );\n var newRemove = _.union(\n _.difference(previous.relationsToRemove, this.relationsToAdd),\n this.relationsToRemove\n );\n\n var newRelation = new AV.Op.Relation(newAdd, newRemove);\n newRelation._targetClassName = this._targetClassName;\n return newRelation;\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n\n _estimate: function(oldValue, object, key) {\n if (!oldValue) {\n var relation = new AV.Relation(object, key);\n relation.targetClassName = this._targetClassName;\n } else if (oldValue instanceof AV.Relation) {\n if (this._targetClassName) {\n if (oldValue.targetClassName) {\n if (oldValue.targetClassName !== this._targetClassName) {\n throw new Error(\n 'Related object must be a ' +\n oldValue.targetClassName +\n ', but a ' +\n this._targetClassName +\n ' was passed in.'\n );\n }\n } else {\n oldValue.targetClassName = this._targetClassName;\n }\n }\n return oldValue;\n } else {\n throw new Error('Op is invalid after previous op.');\n }\n },\n }\n );\n\n AV.Op._registerDecoder('AddRelation', function(json) {\n return new AV.Op.Relation(AV._decode(json.objects), []);\n });\n AV.Op._registerDecoder('RemoveRelation', function(json) {\n return new AV.Op.Relation([], AV._decode(json.objects));\n });\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/op.js","var parent = require('../../es/instance/find');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/instance/find.js\n// module id = 440\n// module chunks = 0 1","var isPrototypeOf = require('../../internals/object-is-prototype-of');\nvar method = require('../array/virtual/find');\n\nvar ArrayPrototype = Array.prototype;\n\nmodule.exports = function (it) {\n var own = it.find;\n return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.find) ? method : own;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/instance/find.js\n// module id = 441\n// module chunks = 0 1","require('../../../modules/es.array.find');\nvar entryVirtual = require('../../../internals/entry-virtual');\n\nmodule.exports = entryVirtual('Array').find;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/virtual/find.js\n// module id = 442\n// module chunks = 0 1","'use strict';\nvar $ = require('../internals/export');\nvar $find = require('../internals/array-iteration').find;\nvar addToUnscopables = require('../internals/add-to-unscopables');\n\nvar FIND = 'find';\nvar SKIPS_HOLES = true;\n\n// Shouldn't skip holes\nif (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });\n\n// `Array.prototype.find` method\n// https://tc39.es/ecma262/#sec-array.prototype.find\n$({ target: 'Array', proto: true, forced: SKIPS_HOLES }, {\n find: function find(callbackfn /* , that = undefined */) {\n return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables(FIND);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.find.js\n// module id = 443\n// module chunks = 0 1","var _ = require('underscore');\n\nmodule.exports = function(AV) {\n /**\n * Creates a new Relation for the given parent object and key. This\n * constructor should rarely be used directly, but rather created by\n * {@link AV.Object#relation}.\n * @param {AV.Object} parent The parent of this relation.\n * @param {String} key The key for this relation on the parent.\n * @see AV.Object#relation\n * @class\n *\n * \n * A class that is used to access all of the children of a many-to-many\n * relationship. Each instance of AV.Relation is associated with a\n * particular parent object and key.\n *
\n */\n AV.Relation = function(parent, key) {\n if (!_.isString(key)) {\n throw new TypeError('key must be a string');\n }\n this.parent = parent;\n this.key = key;\n this.targetClassName = null;\n };\n\n /**\n * Creates a query that can be used to query the parent objects in this relation.\n * @param {String} parentClass The parent class or name.\n * @param {String} relationKey The relation field key in parent.\n * @param {AV.Object} child The child object.\n * @return {AV.Query}\n */\n AV.Relation.reverseQuery = function(parentClass, relationKey, child) {\n var query = new AV.Query(parentClass);\n query.equalTo(relationKey, child._toPointer());\n return query;\n };\n\n _.extend(\n AV.Relation.prototype,\n /** @lends AV.Relation.prototype */ {\n /**\n * Makes sure that this relation has the right parent and key.\n * @private\n */\n _ensureParentAndKey: function(parent, key) {\n this.parent = this.parent || parent;\n this.key = this.key || key;\n if (this.parent !== parent) {\n throw new Error(\n 'Internal Error. Relation retrieved from two different Objects.'\n );\n }\n if (this.key !== key) {\n throw new Error(\n 'Internal Error. Relation retrieved from two different keys.'\n );\n }\n },\n\n /**\n * Adds a AV.Object or an array of AV.Objects to the relation.\n * @param {AV.Object|AV.Object[]} objects The item or items to add.\n */\n add: function(objects) {\n if (!_.isArray(objects)) {\n objects = [objects];\n }\n\n var change = new AV.Op.Relation(objects, []);\n this.parent.set(this.key, change);\n this.targetClassName = change._targetClassName;\n },\n\n /**\n * Removes a AV.Object or an array of AV.Objects from this relation.\n * @param {AV.Object|AV.Object[]} objects The item or items to remove.\n */\n remove: function(objects) {\n if (!_.isArray(objects)) {\n objects = [objects];\n }\n\n var change = new AV.Op.Relation([], objects);\n this.parent.set(this.key, change);\n this.targetClassName = change._targetClassName;\n },\n\n /**\n * Returns a JSON version of the object suitable for saving to disk.\n * @return {Object}\n */\n toJSON: function() {\n return { __type: 'Relation', className: this.targetClassName };\n },\n\n /**\n * Returns a AV.Query that is limited to objects in this\n * relation.\n * @return {AV.Query}\n */\n query: function() {\n var targetClass;\n var query;\n if (!this.targetClassName) {\n targetClass = AV.Object._getSubclass(this.parent.className);\n query = new AV.Query(targetClass);\n query._defaultParams.redirectClassNameForKey = this.key;\n } else {\n targetClass = AV.Object._getSubclass(this.targetClassName);\n query = new AV.Query(targetClass);\n }\n query._addCondition('$relatedTo', 'object', this.parent._toPointer());\n query._addCondition('$relatedTo', 'key', this.key);\n\n return query;\n },\n }\n );\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/relation.js","const _ = require('underscore');\nconst cos = require('./uploader/cos');\nconst qiniu = require('./uploader/qiniu');\nconst s3 = require('./uploader/s3');\nconst AVError = require('./error');\nconst { request, _request: AVRequest } = require('./request');\nconst { tap, transformFetchOptions } = require('./utils');\nconst debug = require('debug')('leancloud:file');\nconst parseBase64 = require('./utils/parse-base64');\n\nmodule.exports = function(AV) {\n // port from browserify path module\n // since react-native packager won't shim node modules.\n const extname = path => {\n if (!_.isString(path)) return '';\n return path.match(\n /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/\n )[4];\n };\n\n const b64Digit = number => {\n if (number < 26) {\n return String.fromCharCode(65 + number);\n }\n if (number < 52) {\n return String.fromCharCode(97 + (number - 26));\n }\n if (number < 62) {\n return String.fromCharCode(48 + (number - 52));\n }\n if (number === 62) {\n return '+';\n }\n if (number === 63) {\n return '/';\n }\n throw new Error('Tried to encode large digit ' + number + ' in base64.');\n };\n\n var encodeBase64 = function(array) {\n var chunks = [];\n chunks.length = Math.ceil(array.length / 3);\n _.times(chunks.length, function(i) {\n var b1 = array[i * 3];\n var b2 = array[i * 3 + 1] || 0;\n var b3 = array[i * 3 + 2] || 0;\n\n var has2 = i * 3 + 1 < array.length;\n var has3 = i * 3 + 2 < array.length;\n\n chunks[i] = [\n b64Digit((b1 >> 2) & 0x3f),\n b64Digit(((b1 << 4) & 0x30) | ((b2 >> 4) & 0x0f)),\n has2 ? b64Digit(((b2 << 2) & 0x3c) | ((b3 >> 6) & 0x03)) : '=',\n has3 ? b64Digit(b3 & 0x3f) : '=',\n ].join('');\n });\n return chunks.join('');\n };\n\n /**\n * An AV.File is a local representation of a file that is saved to the AV\n * cloud.\n * @param name {String} The file's name. This will change to a unique value\n * once the file has finished saving.\n * @param data {Array} The data for the file, as either:\n * 1. an Array of byte value Numbers, or\n * 2. an Object like { base64: \"...\" } with a base64-encoded String.\n * 3. a Blob(File) selected with a file upload control in a browser.\n * 4. an Object like { blob: {uri: \"...\"} } that mimics Blob\n * in some non-browser environments such as React Native.\n * 5. a Buffer in Node.js runtime.\n * 6. a Stream in Node.js runtime.\n *\n * For example:\n * var fileUploadControl = $(\"#profilePhotoFileUpload\")[0];\n * if (fileUploadControl.files.length > 0) {\n * var file = fileUploadControl.files[0];\n * var name = \"photo.jpg\";\n * var file = new AV.File(name, file);\n * file.save().then(function() {\n * // The file has been saved to AV.\n * }, function(error) {\n * // The file either could not be read, or could not be saved to AV.\n * });\n * }\n *\n * @class\n * @param [mimeType] {String} Content-Type header to use for the file. If\n * this is omitted, the content type will be inferred from the name's\n * extension.\n */\n AV.File = function(name, data, mimeType) {\n this.attributes = {\n name,\n url: '',\n metaData: {},\n // 用来存储转换后要上传的 base64 String\n base64: '',\n };\n\n if (_.isString(data)) {\n throw new TypeError(\n 'Creating an AV.File from a String is not yet supported.'\n );\n }\n if (_.isArray(data)) {\n this.attributes.metaData.size = data.length;\n data = { base64: encodeBase64(data) };\n }\n\n this._extName = '';\n this._data = data;\n this._uploadHeaders = {};\n\n if (data && data.blob && typeof data.blob.uri === 'string') {\n this._extName = extname(data.blob.uri);\n }\n\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n if (data.size) {\n this.attributes.metaData.size = data.size;\n }\n if (data.name) {\n this._extName = extname(data.name);\n }\n }\n\n\n let owner;\n if (data && data.owner) {\n owner = data.owner;\n } else if (!AV._config.disableCurrentUser) {\n try {\n owner = AV.User.current();\n } catch (error) {\n if ('SYNC_API_NOT_AVAILABLE' !== error.code) {\n throw error;\n }\n }\n }\n\n this.attributes.metaData.owner = owner ? owner.id : 'unknown';\n\n this.set('mime_type', mimeType);\n };\n\n /**\n * Creates a fresh AV.File object with exists url for saving to AVOS Cloud.\n * @param {String} name the file name\n * @param {String} url the file url.\n * @param {Object} [metaData] the file metadata object.\n * @param {String} [type] Content-Type header to use for the file. If\n * this is omitted, the content type will be inferred from the name's\n * extension.\n * @return {AV.File} the file object\n */\n AV.File.withURL = function(name, url, metaData, type) {\n if (!name || !url) {\n throw new Error('Please provide file name and url');\n }\n var file = new AV.File(name, null, type);\n //copy metaData properties to file.\n if (metaData) {\n for (var prop in metaData) {\n if (!file.attributes.metaData[prop])\n file.attributes.metaData[prop] = metaData[prop];\n }\n }\n file.attributes.url = url;\n //Mark the file is from external source.\n file.attributes.metaData.__source = 'external';\n file.attributes.metaData.size = 0;\n return file;\n };\n\n /**\n * Creates a file object with exists objectId.\n * @param {String} objectId The objectId string\n * @return {AV.File} the file object\n */\n AV.File.createWithoutData = function(objectId) {\n if (!objectId) {\n throw new TypeError('The objectId must be provided');\n }\n var file = new AV.File();\n file.id = objectId;\n return file;\n };\n\n /**\n * Request file censor.\n * @since 4.13.0\n * @param {String} objectId\n * @return {Promise.
Returns the file's metadata JSON object if no arguments is given.Returns the\n * metadata value if a key is given.Set metadata value if key and value are both given.
\n *\n * var metadata = file.metaData(); //Get metadata JSON object.\n * var size = file.metaData('size'); // Get the size metadata value.\n * file.metaData('format', 'jpeg'); //set metadata attribute and value.\n *\n * @return {Object} The file's metadata JSON object.\n * @param {String} attr an optional metadata key.\n * @param {Object} value an optional metadata value.\n **/\n metaData(attr, value) {\n if (attr && value) {\n this.attributes.metaData[attr] = value;\n return this;\n } else if (attr && !value) {\n return this.attributes.metaData[attr];\n } else {\n return this.attributes.metaData;\n }\n },\n\n /**\n * 如果文件是图片,获取图片的缩略图URL。可以传入宽度、高度、质量、格式等参数。\n * @return {String} 缩略图URL\n * @param {Number} width 宽度,单位:像素\n * @param {Number} heigth 高度,单位:像素\n * @param {Number} quality 质量,1-100的数字,默认100\n * @param {Number} scaleToFit 是否将图片自适应大小。默认为true。\n * @param {String} fmt 格式,默认为png,也可以为jpeg,gif等格式。\n */\n\n thumbnailURL(\n width,\n height,\n quality = 100,\n scaleToFit = true,\n fmt = 'png'\n ) {\n const url = this.attributes.url;\n if (!url) {\n throw new Error('Invalid url.');\n }\n if (!width || !height || width <= 0 || height <= 0) {\n throw new Error('Invalid width or height value.');\n }\n if (quality <= 0 || quality > 100) {\n throw new Error('Invalid quality value.');\n }\n const mode = scaleToFit ? 2 : 1;\n return (\n url +\n '?imageView/' +\n mode +\n '/w/' +\n width +\n '/h/' +\n height +\n '/q/' +\n quality +\n '/format/' +\n fmt\n );\n },\n\n /**\n * Returns the file's size.\n * @return {Number} The file's size in bytes.\n **/\n size() {\n return this.metaData().size;\n },\n\n /**\n * Returns the file's owner.\n * @return {String} The file's owner id.\n */\n ownerId() {\n return this.metaData().owner;\n },\n\n /**\n * Destroy the file.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the destroy\n * completes.\n */\n destroy(options) {\n if (!this.id) {\n return Promise.reject(new Error('The file id does not eixst.'));\n }\n var request = AVRequest(\n 'files',\n null,\n this.id,\n 'DELETE',\n null,\n options\n );\n return request;\n },\n\n /**\n * Request Qiniu upload token\n * @param {string} type\n * @return {Promise} Resolved with the response\n * @private\n */\n _fileToken(type, authOptions) {\n let name = this.attributes.name;\n\n let extName = extname(name);\n if (!extName && this._extName) {\n name += this._extName;\n extName = this._extName;\n }\n const data = {\n name,\n keep_file_name: authOptions.keepFileName,\n key: authOptions.key,\n ACL: this._acl,\n mime_type: type,\n metaData: this.attributes.metaData,\n };\n return AVRequest('fileTokens', null, null, 'POST', data, authOptions);\n },\n\n /**\n * @callback UploadProgressCallback\n * @param {XMLHttpRequestProgressEvent} event - The progress event with 'loaded' and 'total' attributes\n */\n /**\n * Saves the file to the AV cloud.\n * @param {AuthOptions} [options] AuthOptions plus:\n * @param {UploadProgressCallback} [options.onprogress] 文件上传进度,在 Node.js 中无效,回调参数说明详见 {@link UploadProgressCallback}。\n * @param {boolean} [options.keepFileName = false] 保留下载文件的文件名。\n * @param {string} [options.key] 指定文件的 key。设置该选项需要使用 masterKey\n * @return {Promise} Promise that is resolved when the save finishes.\n */\n save(options = {}) {\n if (this.id) {\n throw new Error('File is already saved.');\n }\n if (!this._previousSave) {\n if (this._data) {\n let mimeType = this.get('mime_type');\n this._previousSave = this._fileToken(mimeType, options).then(\n uploadInfo => {\n if (uploadInfo.mime_type) {\n mimeType = uploadInfo.mime_type;\n this.set('mime_type', mimeType);\n }\n this._token = uploadInfo.token;\n return Promise.resolve()\n .then(() => {\n const data = this._data;\n if (data && data.base64) {\n return parseBase64(data.base64, mimeType);\n }\n if (data && data.blob) {\n if (!data.blob.type && mimeType) {\n data.blob.type = mimeType;\n }\n if (!data.blob.name) {\n data.blob.name = this.get('name');\n }\n return data.blob;\n }\n if (typeof Blob !== 'undefined' && data instanceof Blob) {\n return data;\n }\n throw new TypeError('malformed file data');\n })\n .then(data => {\n const _options = _.extend({}, options);\n // filter out download progress events\n if (options.onprogress) {\n _options.onprogress = event => {\n if (event.direction === 'download') return;\n return options.onprogress(event);\n };\n }\n switch (uploadInfo.provider) {\n case 's3':\n return s3(uploadInfo, data, this, _options);\n case 'qcloud':\n return cos(uploadInfo, data, this, _options);\n case 'qiniu':\n default:\n return qiniu(uploadInfo, data, this, _options);\n }\n })\n .then(tap(() => this._callback(true)), error => {\n this._callback(false);\n throw error;\n });\n }\n );\n } else if (\n this.attributes.url &&\n this.attributes.metaData.__source === 'external'\n ) {\n // external link file.\n const data = {\n name: this.attributes.name,\n ACL: this._acl,\n metaData: this.attributes.metaData,\n mime_type: this.mimeType,\n url: this.attributes.url,\n };\n this._previousSave = AVRequest(\n 'files',\n null,\n null,\n 'post',\n data,\n options\n ).then(response => {\n this.id = response.objectId;\n return this;\n });\n }\n }\n return this._previousSave;\n },\n\n _callback(success) {\n AVRequest('fileCallback', null, null, 'post', {\n token: this._token,\n result: success,\n }).catch(debug);\n delete this._token;\n delete this._data;\n },\n\n /**\n * fetch the file from server. If the server's representation of the\n * model differs from its current attributes, they will be overriden,\n * @param {Object} fetchOptions Optional options to set 'keys',\n * 'include' and 'includeACL' option.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the fetch\n * completes.\n */\n fetch(fetchOptions, options) {\n if (!this.id) {\n throw new Error('Cannot fetch unsaved file');\n }\n var request = AVRequest(\n 'files',\n null,\n this.id,\n 'GET',\n transformFetchOptions(fetchOptions),\n options\n );\n return request.then(this._finishFetch.bind(this));\n },\n _finishFetch(response) {\n var value = AV.Object.prototype.parse(response);\n value.attributes = {\n name: value.name,\n url: value.url,\n mime_type: value.mime_type,\n bucket: value.bucket,\n };\n value.attributes.metaData = value.metaData || {};\n value.id = value.objectId;\n // clean\n delete value.objectId;\n delete value.metaData;\n delete value.url;\n delete value.name;\n delete value.mime_type;\n delete value.bucket;\n _.extend(this, value);\n return this;\n },\n\n /**\n * Request file censor\n * @since 4.13.0\n * @return {Promise.
You won't normally call this method directly. It is recommended that\n * you use a subclass of AV.Object
instead, created by calling\n * extend
.
However, if you don't want to use a subclass, or aren't sure which\n * subclass is appropriate, you can use this form:
\n * var object = new AV.Object(\"ClassName\");\n *\n * That is basically equivalent to:
\n * var MyClass = AV.Object.extend(\"ClassName\");\n * var object = new MyClass();\n *\n *\n * @param {Object} attributes The initial set of data to store in the object.\n * @param {Object} options A set of Backbone-like options for creating the\n * object. The only option currently supported is \"collection\".\n * @see AV.Object.extend\n *\n * @class\n *\n *
The fundamental unit of AV data, which implements the Backbone Model\n * interface.
\n */\n AV.Object = function(attributes, options) {\n // Allow new AV.Object(\"ClassName\") as a shortcut to _create.\n if (_.isString(attributes)) {\n return AV.Object._create.apply(this, arguments);\n }\n\n attributes = attributes || {};\n if (options && options.parse) {\n attributes = this.parse(attributes);\n attributes = this._mergeMagicFields(attributes);\n }\n var defaults = getValue(this, 'defaults');\n if (defaults) {\n attributes = _.extend({}, defaults, attributes);\n }\n if (options && options.collection) {\n this.collection = options.collection;\n }\n\n this._serverData = {}; // The last known data for this object from cloud.\n this._opSetQueue = [{}]; // List of sets of changes to the data.\n this._flags = {};\n this.attributes = {}; // The best estimate of this's current data.\n\n this._hashedJSON = {}; // Hash of values of containers at last save.\n this._escapedAttributes = {};\n this.cid = _.uniqueId('c');\n this.changed = {};\n this._silent = {};\n this._pending = {};\n this.set(attributes, { silent: true });\n this.changed = {};\n this._silent = {};\n this._pending = {};\n this._hasData = true;\n this._previousAttributes = _.clone(this.attributes);\n this.initialize.apply(this, arguments);\n };\n\n /**\n * @lends AV.Object.prototype\n * @property {String} id The objectId of the AV Object.\n */\n\n /**\n * Saves the given list of AV.Object.\n * If any error is encountered, stops and calls the error handler.\n *\n * @example\n * AV.Object.saveAll([object1, object2, ...]).then(function(list) {\n * // All the objects were saved.\n * }, function(error) {\n * // An error occurred while saving one of the objects.\n * });\n *\n * @param {Array} list A list ofAV.Object
.\n */\n AV.Object.saveAll = function(list, options) {\n return AV.Object._deepSaveAsync(list, null, options);\n };\n\n /**\n * Fetch the given list of AV.Object.\n *\n * @param {AV.Object[]} objects A list of AV.Object
\n * @param {AuthOptions} options\n * @return {Promise.AV.Object
, updated\n */\n\n AV.Object.fetchAll = (objects, options) =>\n Promise.resolve()\n .then(() =>\n _request(\n 'batch',\n null,\n null,\n 'POST',\n {\n requests: _.map(objects, object => {\n if (!object.className)\n throw new Error('object must have className to fetch');\n if (!object.id) throw new Error('object must have id to fetch');\n if (object.dirty())\n throw new Error('object is modified but not saved');\n return {\n method: 'GET',\n path: `/1.1/classes/${object.className}/${object.id}`,\n };\n }),\n },\n options\n )\n )\n .then(function(response) {\n const results = _.map(objects, function(object, i) {\n if (response[i].success) {\n const fetchedAttrs = object.parse(response[i].success);\n object._cleanupUnsetKeys(fetchedAttrs);\n object._finishFetch(fetchedAttrs);\n return object;\n }\n if (response[i].success === null) {\n return new AVError(AVError.OBJECT_NOT_FOUND, 'Object not found.');\n }\n return new AVError(response[i].error.code, response[i].error.error);\n });\n return handleBatchResults(results);\n });\n\n // Attach all inheritable methods to the AV.Object prototype.\n _.extend(\n AV.Object.prototype,\n AV.Events,\n /** @lends AV.Object.prototype */ {\n _fetchWhenSave: false,\n\n /**\n * Initialize is an empty function by default. Override it with your own\n * initialization logic.\n */\n initialize: function() {},\n\n /**\n * Set whether to enable fetchWhenSave option when updating object.\n * When set true, SDK would fetch the latest object after saving.\n * Default is false.\n *\n * @deprecated use AV.Object#save with options.fetchWhenSave instead\n * @param {boolean} enable true to enable fetchWhenSave option.\n */\n fetchWhenSave: function(enable) {\n console.warn(\n 'AV.Object#fetchWhenSave is deprecated, use AV.Object#save with options.fetchWhenSave instead.'\n );\n if (!_.isBoolean(enable)) {\n throw new Error('Expect boolean value for fetchWhenSave');\n }\n this._fetchWhenSave = enable;\n },\n\n /**\n * Returns the object's objectId.\n * @return {String} the objectId.\n */\n getObjectId: function() {\n return this.id;\n },\n\n /**\n * Returns the object's createdAt attribute.\n * @return {Date}\n */\n getCreatedAt: function() {\n return this.createdAt;\n },\n\n /**\n * Returns the object's updatedAt attribute.\n * @return {Date}\n */\n getUpdatedAt: function() {\n return this.updatedAt;\n },\n\n /**\n * Returns a JSON version of the object.\n * @return {Object}\n */\n toJSON: function(key, holder, seenObjects = []) {\n return this._toFullJSON(seenObjects, false);\n },\n\n /**\n * Returns a JSON version of the object with meta data.\n * Inverse to {@link AV.parseJSON}\n * @since 3.0.0\n * @return {Object}\n */\n toFullJSON(seenObjects = []) {\n return this._toFullJSON(seenObjects);\n },\n\n _toFullJSON: function(seenObjects, full = true) {\n var json = _.clone(this.attributes);\n if (_.isArray(seenObjects)) {\n var newSeenObjects = seenObjects.concat(this);\n }\n AV._objectEach(json, function(val, key) {\n json[key] = AV._encode(val, newSeenObjects, undefined, full);\n });\n AV._objectEach(this._operations, function(val, key) {\n json[key] = val;\n });\n\n if (_.has(this, 'id')) {\n json.objectId = this.id;\n }\n ['createdAt', 'updatedAt'].forEach(key => {\n if (_.has(this, key)) {\n const val = this[key];\n json[key] = _.isDate(val) ? val.toJSON() : val;\n }\n });\n if (full) {\n json.__type = 'Object';\n if (_.isArray(seenObjects) && seenObjects.length)\n json.__type = 'Pointer';\n json.className = this.className;\n }\n return json;\n },\n\n /**\n * Updates _hashedJSON to reflect the current state of this object.\n * Adds any changed hash values to the set of pending changes.\n * @private\n */\n _refreshCache: function() {\n var self = this;\n if (self._refreshingCache) {\n return;\n }\n self._refreshingCache = true;\n AV._objectEach(this.attributes, function(value, key) {\n if (value instanceof AV.Object) {\n value._refreshCache();\n } else if (_.isObject(value)) {\n if (self._resetCacheForKey(key)) {\n self.set(key, new AV.Op.Set(value), { silent: true });\n }\n }\n });\n delete self._refreshingCache;\n },\n\n /**\n * Returns true if this object has been modified since its last\n * save/refresh. If an attribute is specified, it returns true only if that\n * particular attribute has been modified since the last save/refresh.\n * @param {String} attr An attribute name (optional).\n * @return {Boolean}\n */\n dirty: function(attr) {\n this._refreshCache();\n\n var currentChanges = _.last(this._opSetQueue);\n\n if (attr) {\n return currentChanges[attr] ? true : false;\n }\n if (!this.id) {\n return true;\n }\n if (_.keys(currentChanges).length > 0) {\n return true;\n }\n return false;\n },\n\n /**\n * Returns the keys of the modified attribute since its last save/refresh.\n * @return {String[]}\n */\n dirtyKeys: function() {\n this._refreshCache();\n var currentChanges = _.last(this._opSetQueue);\n return _.keys(currentChanges);\n },\n\n /**\n * Gets a Pointer referencing this Object.\n * @private\n */\n _toPointer: function() {\n // if (!this.id) {\n // throw new Error(\"Can't serialize an unsaved AV.Object\");\n // }\n return {\n __type: 'Pointer',\n className: this.className,\n objectId: this.id,\n };\n },\n\n /**\n * Gets the value of an attribute.\n * @param {String} attr The string name of an attribute.\n */\n get: function(attr) {\n switch (attr) {\n case 'objectId':\n return this.id;\n case 'createdAt':\n case 'updatedAt':\n return this[attr];\n default:\n return this.attributes[attr];\n }\n },\n\n /**\n * Gets a relation on the given class for the attribute.\n * @param {String} attr The attribute to get the relation for.\n * @return {AV.Relation}\n */\n relation: function(attr) {\n var value = this.get(attr);\n if (value) {\n if (!(value instanceof AV.Relation)) {\n throw new Error('Called relation() on non-relation field ' + attr);\n }\n value._ensureParentAndKey(this, attr);\n return value;\n } else {\n return new AV.Relation(this, attr);\n }\n },\n\n /**\n * Gets the HTML-escaped value of an attribute.\n */\n escape: function(attr) {\n var html = this._escapedAttributes[attr];\n if (html) {\n return html;\n }\n var val = this.attributes[attr];\n var escaped;\n if (isNullOrUndefined(val)) {\n escaped = '';\n } else {\n escaped = _.escape(val.toString());\n }\n this._escapedAttributes[attr] = escaped;\n return escaped;\n },\n\n /**\n * Returns true
if the attribute contains a value that is not\n * null or undefined.\n * @param {String} attr The string name of the attribute.\n * @return {Boolean}\n */\n has: function(attr) {\n return !isNullOrUndefined(this.attributes[attr]);\n },\n\n /**\n * Pulls \"special\" fields like objectId, createdAt, etc. out of attrs\n * and puts them on \"this\" directly. Removes them from attrs.\n * @param attrs - A dictionary with the data for this AV.Object.\n * @private\n */\n _mergeMagicFields: function(attrs) {\n // Check for changes of magic fields.\n var model = this;\n var specialFields = ['objectId', 'createdAt', 'updatedAt'];\n AV._arrayEach(specialFields, function(attr) {\n if (attrs[attr]) {\n if (attr === 'objectId') {\n model.id = attrs[attr];\n } else if (\n (attr === 'createdAt' || attr === 'updatedAt') &&\n !_.isDate(attrs[attr])\n ) {\n model[attr] = AV._parseDate(attrs[attr]);\n } else {\n model[attr] = attrs[attr];\n }\n delete attrs[attr];\n }\n });\n return attrs;\n },\n\n /**\n * Returns the json to be sent to the server.\n * @private\n */\n _startSave: function() {\n this._opSetQueue.push({});\n },\n\n /**\n * Called when a save fails because of an error. Any changes that were part\n * of the save need to be merged with changes made after the save. This\n * might throw an exception is you do conflicting operations. For example,\n * if you do:\n * object.set(\"foo\", \"bar\");\n * object.set(\"invalid field name\", \"baz\");\n * object.save();\n * object.increment(\"foo\");\n * then this will throw when the save fails and the client tries to merge\n * \"bar\" with the +1.\n * @private\n */\n _cancelSave: function() {\n var failedChanges = _.first(this._opSetQueue);\n this._opSetQueue = _.rest(this._opSetQueue);\n var nextChanges = _.first(this._opSetQueue);\n AV._objectEach(failedChanges, function(op, key) {\n var op1 = failedChanges[key];\n var op2 = nextChanges[key];\n if (op1 && op2) {\n nextChanges[key] = op2._mergeWithPrevious(op1);\n } else if (op1) {\n nextChanges[key] = op1;\n }\n });\n this._saving = this._saving - 1;\n },\n\n /**\n * Called when a save completes successfully. This merges the changes that\n * were saved into the known server data, and overrides it with any data\n * sent directly from the server.\n * @private\n */\n _finishSave: function(serverData) {\n // Grab a copy of any object referenced by this object. These instances\n // may have already been fetched, and we don't want to lose their data.\n // Note that doing it like this means we will unify separate copies of the\n // same object, but that's a risk we have to take.\n var fetchedObjects = {};\n AV._traverse(this.attributes, function(object) {\n if (object instanceof AV.Object && object.id && object._hasData) {\n fetchedObjects[object.id] = object;\n }\n });\n\n var savedChanges = _.first(this._opSetQueue);\n this._opSetQueue = _.rest(this._opSetQueue);\n this._applyOpSet(savedChanges, this._serverData);\n this._mergeMagicFields(serverData);\n var self = this;\n AV._objectEach(serverData, function(value, key) {\n self._serverData[key] = AV._decode(value, key);\n\n // Look for any objects that might have become unfetched and fix them\n // by replacing their values with the previously observed values.\n var fetched = AV._traverse(self._serverData[key], function(object) {\n if (object instanceof AV.Object && fetchedObjects[object.id]) {\n return fetchedObjects[object.id];\n }\n });\n if (fetched) {\n self._serverData[key] = fetched;\n }\n });\n this._rebuildAllEstimatedData();\n const opSetQueue = this._opSetQueue.map(_.clone);\n this._refreshCache();\n this._opSetQueue = opSetQueue;\n this._saving = this._saving - 1;\n },\n\n /**\n * Called when a fetch or login is complete to set the known server data to\n * the given object.\n * @private\n */\n _finishFetch: function(serverData, hasData) {\n // Clear out any changes the user might have made previously.\n this._opSetQueue = [{}];\n\n // Bring in all the new server data.\n this._mergeMagicFields(serverData);\n var self = this;\n AV._objectEach(serverData, function(value, key) {\n self._serverData[key] = AV._decode(value, key);\n });\n\n // Refresh the attributes.\n this._rebuildAllEstimatedData();\n\n // Clear out the cache of mutable containers.\n this._refreshCache();\n this._opSetQueue = [{}];\n\n this._hasData = hasData;\n },\n\n /**\n * Applies the set of AV.Op in opSet to the object target.\n * @private\n */\n _applyOpSet: function(opSet, target) {\n var self = this;\n AV._objectEach(opSet, function(change, key) {\n const [value, actualTarget, actualKey] = findValue(target, key);\n setValue(target, key, change._estimate(value, self, key));\n if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {\n delete actualTarget[actualKey];\n }\n });\n },\n\n /**\n * Replaces the cached value for key with the current value.\n * Returns true if the new value is different than the old value.\n * @private\n */\n _resetCacheForKey: function(key) {\n var value = this.attributes[key];\n if (\n _.isObject(value) &&\n !(value instanceof AV.Object) &&\n !(value instanceof AV.File)\n ) {\n var json = JSON.stringify(recursiveToPointer(value));\n if (this._hashedJSON[key] !== json) {\n var wasSet = !!this._hashedJSON[key];\n this._hashedJSON[key] = json;\n return wasSet;\n }\n }\n return false;\n },\n\n /**\n * Populates attributes[key] by starting with the last known data from the\n * server, and applying all of the local changes that have been made to that\n * key since then.\n * @private\n */\n _rebuildEstimatedDataForKey: function(key) {\n var self = this;\n delete this.attributes[key];\n if (this._serverData[key]) {\n this.attributes[key] = this._serverData[key];\n }\n AV._arrayEach(this._opSetQueue, function(opSet) {\n var op = opSet[key];\n if (op) {\n const [value, actualTarget, actualKey, firstKey] = findValue(\n self.attributes,\n key\n );\n setValue(self.attributes, key, op._estimate(value, self, key));\n if (actualTarget && actualTarget[actualKey] === AV.Op._UNSET) {\n delete actualTarget[actualKey];\n }\n self._resetCacheForKey(firstKey);\n }\n });\n },\n\n /**\n * Populates attributes by starting with the last known data from the\n * server, and applying all of the local changes that have been made since\n * then.\n * @private\n */\n _rebuildAllEstimatedData: function() {\n var self = this;\n\n var previousAttributes = _.clone(this.attributes);\n\n this.attributes = _.clone(this._serverData);\n AV._arrayEach(this._opSetQueue, function(opSet) {\n self._applyOpSet(opSet, self.attributes);\n AV._objectEach(opSet, function(op, key) {\n self._resetCacheForKey(key);\n });\n });\n\n // Trigger change events for anything that changed because of the fetch.\n AV._objectEach(previousAttributes, function(oldValue, key) {\n if (self.attributes[key] !== oldValue) {\n self.trigger('change:' + key, self, self.attributes[key], {});\n }\n });\n AV._objectEach(this.attributes, function(newValue, key) {\n if (!_.has(previousAttributes, key)) {\n self.trigger('change:' + key, self, newValue, {});\n }\n });\n },\n\n /**\n * Sets a hash of model attributes on the object, firing\n * \"change\"
unless you choose to silence it.\n *\n * You can call it with an object containing keys and values, or with one\n * key and value. For example:
\n *\n * @example\n * gameTurn.set({\n * player: player1,\n * diceRoll: 2\n * });\n *\n * game.set(\"currentPlayer\", player2);\n *\n * game.set(\"finished\", true);\n *\n * @param {String} key The key to set.\n * @param {Any} value The value to give it.\n * @param {Object} [options]\n * @param {Boolean} [options.silent]\n * @return {AV.Object} self if succeeded, throws if the value is not valid.\n * @see AV.Object#validate\n */\n set: function(key, value, options) {\n var attrs;\n if (_.isObject(key) || isNullOrUndefined(key)) {\n attrs = _.mapObject(key, function(v, k) {\n checkReservedKey(k);\n return AV._decode(v, k);\n });\n options = value;\n } else {\n attrs = {};\n checkReservedKey(key);\n attrs[key] = AV._decode(value, key);\n }\n\n // Extract attributes and options.\n options = options || {};\n if (!attrs) {\n return this;\n }\n if (attrs instanceof AV.Object) {\n attrs = attrs.attributes;\n }\n\n // If the unset option is used, every attribute should be a Unset.\n if (options.unset) {\n AV._objectEach(attrs, function(unused_value, key) {\n attrs[key] = new AV.Op.Unset();\n });\n }\n\n // Apply all the attributes to get the estimated values.\n var dataToValidate = _.clone(attrs);\n var self = this;\n AV._objectEach(dataToValidate, function(value, key) {\n if (value instanceof AV.Op) {\n dataToValidate[key] = value._estimate(\n self.attributes[key],\n self,\n key\n );\n if (dataToValidate[key] === AV.Op._UNSET) {\n delete dataToValidate[key];\n }\n }\n });\n\n // Run validation.\n this._validate(attrs, options);\n\n options.changes = {};\n var escaped = this._escapedAttributes;\n\n // Update attributes.\n AV._arrayEach(_.keys(attrs), function(attr) {\n var val = attrs[attr];\n\n // If this is a relation object we need to set the parent correctly,\n // since the location where it was parsed does not have access to\n // this object.\n if (val instanceof AV.Relation) {\n val.parent = self;\n }\n\n if (!(val instanceof AV.Op)) {\n val = new AV.Op.Set(val);\n }\n\n // See if this change will actually have any effect.\n var isRealChange = true;\n if (\n val instanceof AV.Op.Set &&\n _.isEqual(self.attributes[attr], val.value)\n ) {\n isRealChange = false;\n }\n\n if (isRealChange) {\n delete escaped[attr];\n if (options.silent) {\n self._silent[attr] = true;\n } else {\n options.changes[attr] = true;\n }\n }\n\n var currentChanges = _.last(self._opSetQueue);\n currentChanges[attr] = val._mergeWithPrevious(currentChanges[attr]);\n self._rebuildEstimatedDataForKey(attr);\n\n if (isRealChange) {\n self.changed[attr] = self.attributes[attr];\n if (!options.silent) {\n self._pending[attr] = true;\n }\n } else {\n delete self.changed[attr];\n delete self._pending[attr];\n }\n });\n\n if (!options.silent) {\n this.change(options);\n }\n return this;\n },\n\n /**\n * Remove an attribute from the model, firing\"change\"
unless\n * you choose to silence it. This is a noop if the attribute doesn't\n * exist.\n * @param key {String} The key.\n */\n unset: function(attr, options) {\n options = options || {};\n options.unset = true;\n return this.set(attr, null, options);\n },\n\n /**\n * Atomically increments the value of the given attribute the next time the\n * object is saved. If no amount is specified, 1 is used by default.\n *\n * @param key {String} The key.\n * @param amount {Number} The amount to increment by.\n */\n increment: function(attr, amount) {\n if (_.isUndefined(amount) || _.isNull(amount)) {\n amount = 1;\n }\n return this.set(attr, new AV.Op.Increment(amount));\n },\n\n /**\n * Atomically add an object to the end of the array associated with a given\n * key.\n * @param key {String} The key.\n * @param item {} The item to add.\n */\n add: function(attr, item) {\n return this.set(attr, new AV.Op.Add(ensureArray(item)));\n },\n\n /**\n * Atomically add an object to the array associated with a given key, only\n * if it is not already present in the array. The position of the insert is\n * not guaranteed.\n *\n * @param key {String} The key.\n * @param item {} The object to add.\n */\n addUnique: function(attr, item) {\n return this.set(attr, new AV.Op.AddUnique(ensureArray(item)));\n },\n\n /**\n * Atomically remove all instances of an object from the array associated\n * with a given key.\n *\n * @param key {String} The key.\n * @param item {} The object to remove.\n */\n remove: function(attr, item) {\n return this.set(attr, new AV.Op.Remove(ensureArray(item)));\n },\n\n /**\n * Atomically apply a \"bit and\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitAnd(attr, value) {\n return this.set(attr, new AV.Op.BitAnd(value));\n },\n\n /**\n * Atomically apply a \"bit or\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitOr(attr, value) {\n return this.set(attr, new AV.Op.BitOr(value));\n },\n\n /**\n * Atomically apply a \"bit xor\" operation on the value associated with a\n * given key.\n *\n * @param key {String} The key.\n * @param value {Number} The value to apply.\n */\n bitXor(attr, value) {\n return this.set(attr, new AV.Op.BitXor(value));\n },\n\n /**\n * Returns an instance of a subclass of AV.Op describing what kind of\n * modification has been performed on this field since the last time it was\n * saved. For example, after calling object.increment(\"x\"), calling\n * object.op(\"x\") would return an instance of AV.Op.Increment.\n *\n * @param key {String} The key.\n * @returns {AV.Op} The operation, or undefined if none.\n */\n op: function(attr) {\n return _.last(this._opSetQueue)[attr];\n },\n\n /**\n * Clear all attributes on the model, firing \"change\"
unless\n * you choose to silence it.\n */\n clear: function(options) {\n options = options || {};\n options.unset = true;\n var keysToClear = _.extend(this.attributes, this._operations);\n return this.set(keysToClear, options);\n },\n\n /**\n * Clears any (or specific) changes to the model made since the last save.\n * @param {string|string[]} [keys] specify keys to revert.\n */\n revert(keys) {\n const lastOp = _.last(this._opSetQueue);\n const _keys = ensureArray(keys || _.keys(lastOp));\n _keys.forEach(key => {\n delete lastOp[key];\n });\n this._rebuildAllEstimatedData();\n return this;\n },\n\n /**\n * Returns a JSON-encoded set of operations to be sent with the next save\n * request.\n * @private\n */\n _getSaveJSON: function() {\n var json = _.clone(_.first(this._opSetQueue));\n AV._objectEach(json, function(op, key) {\n json[key] = op.toJSON();\n });\n return json;\n },\n\n /**\n * Returns true if this object can be serialized for saving.\n * @private\n */\n _canBeSerialized: function() {\n return AV.Object._canBeSerializedAsValue(this.attributes);\n },\n\n /**\n * Fetch the model from the server. If the server's representation of the\n * model differs from its current attributes, they will be overriden,\n * triggering a \"change\"
event.\n * @param {Object} fetchOptions Optional options to set 'keys',\n * 'include' and 'includeACL' option.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the fetch\n * completes.\n */\n fetch: function(fetchOptions = {}, options) {\n if (!this.id) {\n throw new Error('Cannot fetch unsaved object');\n }\n var self = this;\n var request = _request(\n 'classes',\n this.className,\n this.id,\n 'GET',\n transformFetchOptions(fetchOptions),\n options\n );\n return request.then(function(response) {\n const fetchedAttrs = self.parse(response);\n self._cleanupUnsetKeys(\n fetchedAttrs,\n fetchOptions.keys\n ? ensureArray(fetchOptions.keys)\n .join(',')\n .split(',')\n : undefined\n );\n self._finishFetch(fetchedAttrs, true);\n return self;\n });\n },\n\n _cleanupUnsetKeys(fetchedAttrs, fetchedKeys = _.keys(this._serverData)) {\n _.forEach(fetchedKeys, key => {\n if (fetchedAttrs[key] === undefined) delete this._serverData[key];\n });\n },\n\n /**\n * Set a hash of model attributes, and save the model to the server.\n * updatedAt will be updated when the request returns.\n * You can either call it as:\n * object.save();\n * or
\n * object.save(null, options);\n * or
\n * object.save(attrs, options);\n * or
\n * object.save(key, value, options);\n *\n * @example\n * gameTurn.save({\n * player: \"Jake Cutter\",\n * diceRoll: 2\n * }).then(function(gameTurnAgain) {\n * // The save was successful.\n * }, function(error) {\n * // The save failed. Error is an instance of AVError.\n * });\n *\n * @param {AuthOptions} options AuthOptions plus:\n * @param {Boolean} options.fetchWhenSave fetch and update object after save succeeded\n * @param {AV.Query} options.query Save object only when it matches the query\n * @return {Promise} A promise that is fulfilled when the save\n * completes.\n * @see AVError\n */\n save: function(arg1, arg2, arg3) {\n var attrs, current, options;\n if (_.isObject(arg1) || isNullOrUndefined(arg1)) {\n attrs = arg1;\n options = arg2;\n } else {\n attrs = {};\n attrs[arg1] = arg2;\n options = arg3;\n }\n\n options = _.clone(options) || {};\n if (options.wait) {\n current = _.clone(this.attributes);\n }\n\n var setOptions = _.clone(options) || {};\n if (setOptions.wait) {\n setOptions.silent = true;\n }\n if (attrs) {\n this.set(attrs, setOptions);\n }\n\n var model = this;\n\n var unsavedChildren = [];\n var unsavedFiles = [];\n AV.Object._findUnsavedChildren(model, unsavedChildren, unsavedFiles);\n if (unsavedChildren.length + unsavedFiles.length > 1) {\n return AV.Object._deepSaveAsync(this, model, options);\n }\n\n this._startSave();\n this._saving = (this._saving || 0) + 1;\n\n this._allPreviousSaves = this._allPreviousSaves || Promise.resolve();\n this._allPreviousSaves = this._allPreviousSaves\n .catch(e => {})\n .then(function() {\n var method = model.id ? 'PUT' : 'POST';\n\n var json = model._getSaveJSON();\n var query = {};\n\n if (model._fetchWhenSave || options.fetchWhenSave) {\n query['new'] = 'true';\n }\n // user login option\n if (options._failOnNotExist) {\n query.failOnNotExist = 'true';\n }\n\n if (options.query) {\n var queryParams;\n if (typeof options.query._getParams === 'function') {\n queryParams = options.query._getParams();\n if (queryParams) {\n query.where = queryParams.where;\n }\n }\n if (!query.where) {\n var error = new Error('options.query is not an AV.Query');\n throw error;\n }\n }\n\n _.extend(json, model._flags);\n\n var route = 'classes';\n var className = model.className;\n if (model.className === '_User' && !model.id) {\n // Special-case user sign-up.\n route = 'users';\n className = null;\n }\n //hook makeRequest in options.\n var makeRequest = options._makeRequest || _request;\n var requestPromise = makeRequest(\n route,\n className,\n model.id,\n method,\n json,\n options,\n query\n );\n\n requestPromise = requestPromise.then(\n function(resp) {\n var serverAttrs = model.parse(resp);\n if (options.wait) {\n serverAttrs = _.extend(attrs || {}, serverAttrs);\n }\n model._finishSave(serverAttrs);\n if (options.wait) {\n model.set(current, setOptions);\n }\n return model;\n },\n function(error) {\n model._cancelSave();\n throw error;\n }\n );\n\n return requestPromise;\n });\n return this._allPreviousSaves;\n },\n\n /**\n * Destroy this model on the server if it was already persisted.\n * Optimistically removes the model from its collection, if it has one.\n * @param {AuthOptions} options AuthOptions plus:\n * @param {Boolean} [options.wait] wait for the server to respond\n * before removal.\n *\n * @return {Promise} A promise that is fulfilled when the destroy\n * completes.\n */\n destroy: function(options) {\n options = options || {};\n var model = this;\n\n var triggerDestroy = function() {\n model.trigger('destroy', model, model.collection, options);\n };\n\n if (!this.id) {\n return triggerDestroy();\n }\n\n if (!options.wait) {\n triggerDestroy();\n }\n\n var request = _request(\n 'classes',\n this.className,\n this.id,\n 'DELETE',\n this._flags,\n options\n );\n return request.then(function() {\n if (options.wait) {\n triggerDestroy();\n }\n return model;\n });\n },\n\n /**\n * Converts a response into the hash of attributes to be set on the model.\n * @ignore\n */\n parse: function(resp) {\n var output = _.clone(resp);\n ['createdAt', 'updatedAt'].forEach(function(key) {\n if (output[key]) {\n output[key] = AV._parseDate(output[key]);\n }\n });\n if (output.createdAt && !output.updatedAt) {\n output.updatedAt = output.createdAt;\n }\n return output;\n },\n\n /**\n * Creates a new model with identical attributes to this one.\n * @return {AV.Object}\n */\n clone: function() {\n return new this.constructor(this.attributes);\n },\n\n /**\n * Returns true if this object has never been saved to AV.\n * @return {Boolean}\n */\n isNew: function() {\n return !this.id;\n },\n\n /**\n * Call this method to manually fire a `\"change\"` event for this model and\n * a `\"change:attribute\"` event for each changed attribute.\n * Calling this will cause all objects observing the model to update.\n */\n change: function(options) {\n options = options || {};\n var changing = this._changing;\n this._changing = true;\n\n // Silent changes become pending changes.\n var self = this;\n AV._objectEach(this._silent, function(attr) {\n self._pending[attr] = true;\n });\n\n // Silent changes are triggered.\n var changes = _.extend({}, options.changes, this._silent);\n this._silent = {};\n AV._objectEach(changes, function(unused_value, attr) {\n self.trigger('change:' + attr, self, self.get(attr), options);\n });\n if (changing) {\n return this;\n }\n\n // This is to get around lint not letting us make a function in a loop.\n var deleteChanged = function(value, attr) {\n if (!self._pending[attr] && !self._silent[attr]) {\n delete self.changed[attr];\n }\n };\n\n // Continue firing `\"change\"` events while there are pending changes.\n while (!_.isEmpty(this._pending)) {\n this._pending = {};\n this.trigger('change', this, options);\n // Pending and silent changes still remain.\n AV._objectEach(this.changed, deleteChanged);\n self._previousAttributes = _.clone(this.attributes);\n }\n\n this._changing = false;\n return this;\n },\n\n /**\n * Gets the previous value of an attribute, recorded at the time the last\n *
\"change\"
event was fired.\n * @param {String} attr Name of the attribute to get.\n */\n previous: function(attr) {\n if (!arguments.length || !this._previousAttributes) {\n return null;\n }\n return this._previousAttributes[attr];\n },\n\n /**\n * Gets all of the attributes of the model at the time of the previous\n * \"change\"
event.\n * @return {Object}\n */\n previousAttributes: function() {\n return _.clone(this._previousAttributes);\n },\n\n /**\n * Checks if the model is currently in a valid state. It's only possible to\n * get into an *invalid* state if you're using silent changes.\n * @return {Boolean}\n */\n isValid: function() {\n try {\n this.validate(this.attributes);\n } catch (error) {\n return false;\n }\n return true;\n },\n\n /**\n * You should not call this function directly unless you subclass\n * AV.Object
, in which case you can override this method\n * to provide additional validation on set
and\n * save
. Your implementation should throw an Error if\n * the attrs is invalid\n *\n * @param {Object} attrs The current data to validate.\n * @see AV.Object#set\n */\n validate: function(attrs) {\n if (_.has(attrs, 'ACL') && !(attrs.ACL instanceof AV.ACL)) {\n throw new AVError(AVError.OTHER_CAUSE, 'ACL must be a AV.ACL.');\n }\n },\n\n /**\n * Run validation against a set of incoming attributes, returning `true`\n * if all is well. If a specific `error` callback has been passed,\n * call that instead of firing the general `\"error\"` event.\n * @private\n */\n _validate: function(attrs, options) {\n if (options.silent || !this.validate) {\n return;\n }\n attrs = _.extend({}, this.attributes, attrs);\n this.validate(attrs);\n },\n\n /**\n * Returns the ACL for this object.\n * @returns {AV.ACL} An instance of AV.ACL.\n * @see AV.Object#get\n */\n getACL: function() {\n return this.get('ACL');\n },\n\n /**\n * Sets the ACL to be used for this object.\n * @param {AV.ACL} acl An instance of AV.ACL.\n * @param {Object} options Optional Backbone-like options object to be\n * passed in to set.\n * @return {AV.Object} self\n * @see AV.Object#set\n */\n setACL: function(acl, options) {\n return this.set('ACL', acl, options);\n },\n\n disableBeforeHook: function() {\n this.ignoreHook('beforeSave');\n this.ignoreHook('beforeUpdate');\n this.ignoreHook('beforeDelete');\n },\n\n disableAfterHook: function() {\n this.ignoreHook('afterSave');\n this.ignoreHook('afterUpdate');\n this.ignoreHook('afterDelete');\n },\n\n ignoreHook: function(hookName) {\n if (\n !_.contains(\n [\n 'beforeSave',\n 'afterSave',\n 'beforeUpdate',\n 'afterUpdate',\n 'beforeDelete',\n 'afterDelete',\n ],\n hookName\n )\n ) {\n throw new Error('Unsupported hookName: ' + hookName);\n }\n\n if (!AV.hookKey) {\n throw new Error('ignoreHook required hookKey');\n }\n\n if (!this._flags.__ignore_hooks) {\n this._flags.__ignore_hooks = [];\n }\n\n this._flags.__ignore_hooks.push(hookName);\n },\n }\n );\n\n /**\n * Creates an instance of a subclass of AV.Object for the give classname\n * and id.\n * @param {String|Function} class the className or a subclass of AV.Object.\n * @param {String} id The object id of this model.\n * @return {AV.Object} A new subclass instance of AV.Object.\n */\n AV.Object.createWithoutData = (klass, id, hasData) => {\n let _klass;\n if (_.isString(klass)) {\n _klass = AV.Object._getSubclass(klass);\n } else if (klass.prototype && klass.prototype instanceof AV.Object) {\n _klass = klass;\n } else {\n throw new Error('class must be a string or a subclass of AV.Object.');\n }\n if (!id) {\n throw new TypeError('The objectId must be provided');\n }\n const object = new _klass();\n object.id = id;\n object._hasData = hasData;\n return object;\n };\n /**\n * Delete objects in batch.\n * @param {AV.Object[]} objects The AV.Object
array to be deleted.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the save\n * completes.\n */\n AV.Object.destroyAll = function(objects, options = {}) {\n if (!objects || objects.length === 0) {\n return Promise.resolve();\n }\n const objectsByClassNameAndFlags = _.groupBy(objects, object =>\n JSON.stringify({\n className: object.className,\n flags: object._flags,\n })\n );\n const body = {\n requests: _.map(objectsByClassNameAndFlags, objects => {\n const ids = _.map(objects, 'id').join(',');\n return {\n method: 'DELETE',\n path: `/1.1/classes/${objects[0].className}/${ids}`,\n body: objects[0]._flags,\n };\n }),\n };\n return _request('batch', null, null, 'POST', body, options).then(\n response => {\n const firstError = _.find(response, result => !result.success);\n if (firstError)\n throw new AVError(firstError.error.code, firstError.error.error);\n return undefined;\n }\n );\n };\n\n /**\n * Returns the appropriate subclass for making new instances of the given\n * className string.\n * @private\n */\n AV.Object._getSubclass = function(className) {\n if (!_.isString(className)) {\n throw new Error('AV.Object._getSubclass requires a string argument.');\n }\n var ObjectClass = AV.Object._classMap[className];\n if (!ObjectClass) {\n ObjectClass = AV.Object.extend(className);\n AV.Object._classMap[className] = ObjectClass;\n }\n return ObjectClass;\n };\n\n /**\n * Creates an instance of a subclass of AV.Object for the given classname.\n * @private\n */\n AV.Object._create = function(className, attributes, options) {\n var ObjectClass = AV.Object._getSubclass(className);\n return new ObjectClass(attributes, options);\n };\n\n // Set up a map of className to class so that we can create new instances of\n // AV Objects from JSON automatically.\n AV.Object._classMap = {};\n\n AV.Object._extend = AV._extend;\n\n /**\n * Creates a new model with defined attributes,\n * It's the same with\n * \n * new AV.Object(attributes, options);\n *\n * @param {Object} attributes The initial set of data to store in the object.\n * @param {Object} options A set of Backbone-like options for creating the\n * object. The only option currently supported is \"collection\".\n * @return {AV.Object}\n * @since v0.4.4\n * @see AV.Object\n * @see AV.Object.extend\n */\n AV.Object['new'] = function(attributes, options) {\n return new AV.Object(attributes, options);\n };\n\n /**\n * Creates a new subclass of AV.Object for the given AV class name.\n *\n *
Every extension of a AV class will inherit from the most recent\n * previous extension of that class. When a AV.Object is automatically\n * created by parsing JSON, it will use the most recent extension of that\n * class.
\n *\n * @example\n * var MyClass = AV.Object.extend(\"MyClass\", {\n * // Instance properties\n * }, {\n * // Class properties\n * });\n *\n * @param {String} className The name of the AV class backing this model.\n * @param {Object} protoProps Instance properties to add to instances of the\n * class returned from this method.\n * @param {Object} classProps Class properties to add the class returned from\n * this method.\n * @return {Class} A new subclass of AV.Object.\n */\n AV.Object.extend = function(className, protoProps, classProps) {\n // Handle the case with only two args.\n if (!_.isString(className)) {\n if (className && _.has(className, 'className')) {\n return AV.Object.extend(className.className, className, protoProps);\n } else {\n throw new Error(\n \"AV.Object.extend's first argument should be the className.\"\n );\n }\n }\n\n // If someone tries to subclass \"User\", coerce it to the right type.\n if (className === 'User') {\n className = '_User';\n }\n\n var NewClassObject = null;\n if (_.has(AV.Object._classMap, className)) {\n var OldClassObject = AV.Object._classMap[className];\n // This new subclass has been told to extend both from \"this\" and from\n // OldClassObject. This is multiple inheritance, which isn't supported.\n // For now, let's just pick one.\n if (protoProps || classProps) {\n NewClassObject = OldClassObject._extend(protoProps, classProps);\n } else {\n return OldClassObject;\n }\n } else {\n protoProps = protoProps || {};\n protoProps._className = className;\n NewClassObject = this._extend(protoProps, classProps);\n }\n // Extending a subclass should reuse the classname automatically.\n NewClassObject.extend = function(arg0) {\n if (_.isString(arg0) || (arg0 && _.has(arg0, 'className'))) {\n return AV.Object.extend.apply(NewClassObject, arguments);\n }\n var newArguments = [className].concat(_.toArray(arguments));\n return AV.Object.extend.apply(NewClassObject, newArguments);\n };\n // Add the query property descriptor.\n Object.defineProperty(\n NewClassObject,\n 'query',\n Object.getOwnPropertyDescriptor(AV.Object, 'query')\n );\n NewClassObject['new'] = function(attributes, options) {\n return new NewClassObject(attributes, options);\n };\n AV.Object._classMap[className] = NewClassObject;\n return NewClassObject;\n };\n\n // ES6 class syntax support\n Object.defineProperty(AV.Object.prototype, 'className', {\n get: function() {\n const className =\n this._className ||\n this.constructor._LCClassName ||\n this.constructor.name;\n // If someone tries to subclass \"User\", coerce it to the right type.\n if (className === 'User') {\n return '_User';\n }\n return className;\n },\n });\n\n /**\n * Register a class.\n * If a subclass ofAV.Object
is defined with your own implement\n * rather then AV.Object.extend
, the subclass must be registered.\n * @param {Function} klass A subclass of AV.Object
\n * @param {String} [name] Specify the name of the class. Useful when the class might be uglified.\n * @example\n * class Person extend AV.Object {}\n * AV.Object.register(Person);\n */\n AV.Object.register = (klass, name) => {\n if (!(klass.prototype instanceof AV.Object)) {\n throw new Error('registered class is not a subclass of AV.Object');\n }\n const className = name || klass.name;\n if (!className.length) {\n throw new Error('registered class must be named');\n }\n if (name) {\n klass._LCClassName = name;\n }\n AV.Object._classMap[className] = klass;\n };\n\n /**\n * Get a new Query of the current class\n * @name query\n * @memberof AV.Object\n * @type AV.Query\n * @readonly\n * @since v3.1.0\n * @example\n * const Post = AV.Object.extend('Post');\n * Post.query.equalTo('author', 'leancloud').find().then();\n */\n Object.defineProperty(AV.Object, 'query', {\n get() {\n return new AV.Query(this.prototype.className);\n },\n });\n\n AV.Object._findUnsavedChildren = function(objects, children, files) {\n AV._traverse(objects, function(object) {\n if (object instanceof AV.Object) {\n if (object.dirty()) {\n children.push(object);\n }\n return;\n }\n\n if (object instanceof AV.File) {\n if (!object.id) {\n files.push(object);\n }\n return;\n }\n });\n };\n\n AV.Object._canBeSerializedAsValue = function(object) {\n var canBeSerializedAsValue = true;\n\n if (object instanceof AV.Object || object instanceof AV.File) {\n canBeSerializedAsValue = !!object.id;\n } else if (_.isArray(object)) {\n AV._arrayEach(object, function(child) {\n if (!AV.Object._canBeSerializedAsValue(child)) {\n canBeSerializedAsValue = false;\n }\n });\n } else if (_.isObject(object)) {\n AV._objectEach(object, function(child) {\n if (!AV.Object._canBeSerializedAsValue(child)) {\n canBeSerializedAsValue = false;\n }\n });\n }\n\n return canBeSerializedAsValue;\n };\n\n AV.Object._deepSaveAsync = function(object, model, options) {\n var unsavedChildren = [];\n var unsavedFiles = [];\n AV.Object._findUnsavedChildren(object, unsavedChildren, unsavedFiles);\n\n unsavedFiles = _.uniq(unsavedFiles);\n\n var promise = Promise.resolve();\n _.each(unsavedFiles, function(file) {\n promise = promise.then(function() {\n return file.save();\n });\n });\n\n var objects = _.uniq(unsavedChildren);\n var remaining = _.uniq(objects);\n\n return promise\n .then(function() {\n return continueWhile(\n function() {\n return remaining.length > 0;\n },\n function() {\n // Gather up all the objects that can be saved in this batch.\n var batch = [];\n var newRemaining = [];\n AV._arrayEach(remaining, function(object) {\n if (object._canBeSerialized()) {\n batch.push(object);\n } else {\n newRemaining.push(object);\n }\n });\n remaining = newRemaining;\n\n // If we can't save any objects, there must be a circular reference.\n if (batch.length === 0) {\n return Promise.reject(\n new AVError(\n AVError.OTHER_CAUSE,\n 'Tried to save a batch with a cycle.'\n )\n );\n }\n\n // Reserve a spot in every object's save queue.\n var readyToStart = Promise.resolve(\n _.map(batch, function(object) {\n return object._allPreviousSaves || Promise.resolve();\n })\n );\n\n // Save a single batch, whether previous saves succeeded or failed.\n const bathSavePromise = readyToStart.then(() =>\n _request(\n 'batch',\n null,\n null,\n 'POST',\n {\n requests: _.map(batch, function(object) {\n var method = object.id ? 'PUT' : 'POST';\n\n var json = object._getSaveJSON();\n\n _.extend(json, object._flags);\n\n var route = 'classes';\n var className = object.className;\n var path = `/${route}/${className}`;\n if (object.className === '_User' && !object.id) {\n // Special-case user sign-up.\n path = '/users';\n }\n\n var path = `/1.1${path}`;\n if (object.id) {\n path = path + '/' + object.id;\n }\n\n object._startSave();\n\n return {\n method: method,\n path: path,\n body: json,\n params:\n options && options.fetchWhenSave\n ? { fetchWhenSave: true }\n : undefined,\n };\n }),\n },\n options\n ).then(function(response) {\n const results = _.map(batch, function(object, i) {\n if (response[i].success) {\n object._finishSave(object.parse(response[i].success));\n return object;\n }\n object._cancelSave();\n return new AVError(\n response[i].error.code,\n response[i].error.error\n );\n });\n return handleBatchResults(results);\n })\n );\n AV._arrayEach(batch, function(object) {\n object._allPreviousSaves = bathSavePromise;\n });\n return bathSavePromise;\n }\n );\n })\n .then(function() {\n return object;\n });\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/object.js","var arrayWithHoles = require(\"./arrayWithHoles.js\");\n\nvar iterableToArrayLimit = require(\"./iterableToArrayLimit.js\");\n\nvar unsupportedIterableToArray = require(\"./unsupportedIterableToArray.js\");\n\nvar nonIterableRest = require(\"./nonIterableRest.js\");\n\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}\n\nmodule.exports = _slicedToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/slicedToArray.js\n// module id = 501\n// module chunks = 0 1","var _Array$isArray = require(\"@babel/runtime-corejs3/core-js/array/is-array\");\n\nfunction _arrayWithHoles(arr) {\n if (_Array$isArray(arr)) return arr;\n}\n\nmodule.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/arrayWithHoles.js\n// module id = 502\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/array/is-array\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/array/is-array.js\n// module id = 503\n// module chunks = 0 1","module.exports = require('../../full/array/is-array');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/array/is-array.js\n// module id = 504\n// module chunks = 0 1","var parent = require('../../actual/array/is-array');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/array/is-array.js\n// module id = 505\n// module chunks = 0 1","var parent = require('../../stable/array/is-array');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/array/is-array.js\n// module id = 506\n// module chunks = 0 1","var parent = require('../../es/array/is-array');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/array/is-array.js\n// module id = 507\n// module chunks = 0 1","require('../../modules/es.array.is-array');\nvar path = require('../../internals/path');\n\nmodule.exports = path.Array.isArray;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/array/is-array.js\n// module id = 508\n// module chunks = 0 1","var $ = require('../internals/export');\nvar isArray = require('../internals/is-array');\n\n// `Array.isArray` method\n// https://tc39.es/ecma262/#sec-array.isarray\n$({ target: 'Array', stat: true }, {\n isArray: isArray\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.array.is-array.js\n// module id = 509\n// module chunks = 0 1","var _Symbol = require(\"@babel/runtime-corejs3/core-js/symbol\");\n\nvar _getIteratorMethod = require(\"@babel/runtime-corejs3/core-js/get-iterator-method\");\n\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof _Symbol !== \"undefined\" && _getIteratorMethod(arr) || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n\nmodule.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/iterableToArrayLimit.js\n// module id = 510\n// module chunks = 0 1","var _sliceInstanceProperty = require(\"@babel/runtime-corejs3/core-js/instance/slice\");\n\nvar _Array$from = require(\"@babel/runtime-corejs3/core-js/array/from\");\n\nvar arrayLikeToArray = require(\"./arrayLikeToArray.js\");\n\nfunction _unsupportedIterableToArray(o, minLen) {\n var _context;\n\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n\n var n = _sliceInstanceProperty(_context = Object.prototype.toString.call(o)).call(_context, 8, -1);\n\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return _Array$from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}\n\nmodule.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/unsupportedIterableToArray.js\n// module id = 511\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/instance/slice\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/instance/slice.js\n// module id = 512\n// module chunks = 0 1","module.exports = require('../../full/instance/slice');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/instance/slice.js\n// module id = 513\n// module chunks = 0 1","var parent = require('../../actual/instance/slice');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/instance/slice.js\n// module id = 514\n// module chunks = 0 1","var parent = require('../../stable/instance/slice');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/instance/slice.js\n// module id = 515\n// module chunks = 0 1","module.exports = require(\"core-js-pure/features/array/from\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js/array/from.js\n// module id = 516\n// module chunks = 0 1","module.exports = require('../../full/array/from');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/features/array/from.js\n// module id = 517\n// module chunks = 0 1","var parent = require('../../actual/array/from');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/full/array/from.js\n// module id = 518\n// module chunks = 0 1","var parent = require('../../stable/array/from');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/actual/array/from.js\n// module id = 519\n// module chunks = 0 1","function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}\n\nmodule.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/arrayLikeToArray.js\n// module id = 520\n// module chunks = 0 1","function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nmodule.exports = _nonIterableRest, module.exports.__esModule = true, module.exports[\"default\"] = module.exports;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/helpers/nonIterableRest.js\n// module id = 521\n// module chunks = 0 1","module.exports = require(\"core-js-pure/stable/object/get-own-property-descriptor\");\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor.js\n// module id = 522\n// module chunks = 0 1","var parent = require('../../es/object/get-own-property-descriptor');\n\nmodule.exports = parent;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/stable/object/get-own-property-descriptor.js\n// module id = 523\n// module chunks = 0 1","require('../../modules/es.object.get-own-property-descriptor');\nvar path = require('../../internals/path');\n\nvar Object = path.Object;\n\nvar getOwnPropertyDescriptor = module.exports = function getOwnPropertyDescriptor(it, key) {\n return Object.getOwnPropertyDescriptor(it, key);\n};\n\nif (Object.getOwnPropertyDescriptor.sham) getOwnPropertyDescriptor.sham = true;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/es/object/get-own-property-descriptor.js\n// module id = 524\n// module chunks = 0 1","var $ = require('../internals/export');\nvar fails = require('../internals/fails');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar nativeGetOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar DESCRIPTORS = require('../internals/descriptors');\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeGetOwnPropertyDescriptor(1); });\nvar FORCED = !DESCRIPTORS || FAILS_ON_PRIMITIVES;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor\n$({ target: 'Object', stat: true, forced: FORCED, sham: !DESCRIPTORS }, {\n getOwnPropertyDescriptor: function getOwnPropertyDescriptor(it, key) {\n return nativeGetOwnPropertyDescriptor(toIndexedObject(it), key);\n }\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/core-js-pure/modules/es.object.get-own-property-descriptor.js\n// module id = 525\n// module chunks = 0 1","const _ = require('underscore');\nconst AVError = require('./error');\n\nmodule.exports = function(AV) {\n AV.Role = AV.Object.extend(\n '_Role',\n /** @lends AV.Role.prototype */ {\n // Instance Methods\n\n /**\n * Represents a Role on the AV server. Roles represent groupings of\n * Users for the purposes of granting permissions (e.g. specifying an ACL\n * for an Object). Roles are specified by their sets of child users and\n * child roles, all of which are granted any permissions that the parent\n * role has.\n *\n * Roles must have a name (which cannot be changed after creation of the\n * role), and must specify an ACL.
\n * An AV.Role is a local representation of a role persisted to the AV\n * cloud.\n * @class AV.Role\n * @param {String} name The name of the Role to create.\n * @param {AV.ACL} acl The ACL for this role.\n */\n constructor: function(name, acl) {\n if (_.isString(name)) {\n AV.Object.prototype.constructor.call(this, null, null);\n this.setName(name);\n } else {\n AV.Object.prototype.constructor.call(this, name, acl);\n }\n if (acl) {\n if (!(acl instanceof AV.ACL)) {\n throw new TypeError('acl must be an instance of AV.ACL');\n } else {\n this.setACL(acl);\n }\n }\n },\n\n /**\n * Gets the name of the role. You can alternatively call role.get(\"name\")\n *\n * @return {String} the name of the role.\n */\n getName: function() {\n return this.get('name');\n },\n\n /**\n * Sets the name for a role. This value must be set before the role has\n * been saved to the server, and cannot be set once the role has been\n * saved.\n *\n *\n * A role's name can only contain alphanumeric characters, _, -, and\n * spaces.\n *
\n *\n *This is equivalent to calling role.set(\"name\", name)
\n *\n * @param {String} name The name of the role.\n */\n setName: function(name, options) {\n return this.set('name', name, options);\n },\n\n /**\n * Gets the AV.Relation for the AV.Users that are direct\n * children of this role. These users are granted any privileges that this\n * role has been granted (e.g. read or write access through ACLs). You can\n * add or remove users from the role through this relation.\n *\n *This is equivalent to calling role.relation(\"users\")
\n *\n * @return {AV.Relation} the relation for the users belonging to this\n * role.\n */\n getUsers: function() {\n return this.relation('users');\n },\n\n /**\n * Gets the AV.Relation for the AV.Roles that are direct\n * children of this role. These roles' users are granted any privileges that\n * this role has been granted (e.g. read or write access through ACLs). You\n * can add or remove child roles from this role through this relation.\n *\n *This is equivalent to calling role.relation(\"roles\")
\n *\n * @return {AV.Relation} the relation for the roles belonging to this\n * role.\n */\n getRoles: function() {\n return this.relation('roles');\n },\n\n /**\n * @ignore\n */\n validate: function(attrs, options) {\n if ('name' in attrs && attrs.name !== this.getName()) {\n var newName = attrs.name;\n if (this.id && this.id !== attrs.objectId) {\n // Check to see if the objectId being set matches this.id.\n // This happens during a fetch -- the id is set before calling fetch.\n // Let the name be set in this case.\n return new AVError(\n AVError.OTHER_CAUSE,\n \"A role's name can only be set before it has been saved.\"\n );\n }\n if (!_.isString(newName)) {\n return new AVError(\n AVError.OTHER_CAUSE,\n \"A role's name must be a String.\"\n );\n }\n if (!/^[0-9a-zA-Z\\-_ ]+$/.test(newName)) {\n return new AVError(\n AVError.OTHER_CAUSE,\n \"A role's name can only contain alphanumeric characters, _,\" +\n ' -, and spaces.'\n );\n }\n }\n if (AV.Object.prototype.validate) {\n return AV.Object.prototype.validate.call(this, attrs, options);\n }\n return false;\n },\n }\n );\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/role.js","const _ = require('underscore');\nconst uuid = require('uuid/v4');\nconst AVError = require('./error');\nconst { _request: AVRequest, request } = require('./request');\nconst { getAdapter } = require('./adapter');\n\nconst PLATFORM_ANONYMOUS = 'anonymous';\nconst PLATFORM_QQAPP = 'lc_qqapp';\n\nconst mergeUnionDataIntoAuthData = (defaultUnionIdPlatform = 'weixin') => (\n authData,\n unionId,\n { unionIdPlatform = defaultUnionIdPlatform, asMainAccount = false } = {}\n) => {\n if (typeof unionId !== 'string')\n throw new AVError(AVError.OTHER_CAUSE, 'unionId is not a string');\n if (typeof unionIdPlatform !== 'string')\n throw new AVError(AVError.OTHER_CAUSE, 'unionIdPlatform is not a string');\n\n return _.extend({}, authData, {\n platform: unionIdPlatform,\n unionid: unionId,\n main_account: Boolean(asMainAccount),\n });\n};\n\nmodule.exports = function(AV) {\n /**\n * @class\n *\n *An AV.User object is a local representation of a user persisted to the\n * LeanCloud server. This class is a subclass of an AV.Object, and retains the\n * same functionality of an AV.Object, but also extends it with various\n * user specific methods, like authentication, signing up, and validation of\n * uniqueness.
\n */\n AV.User = AV.Object.extend(\n '_User',\n /** @lends AV.User.prototype */ {\n // Instance Variables\n _isCurrentUser: false,\n\n // Instance Methods\n\n /**\n * Internal method to handle special fields in a _User response.\n * @private\n */\n _mergeMagicFields: function(attrs) {\n if (attrs.sessionToken) {\n this._sessionToken = attrs.sessionToken;\n delete attrs.sessionToken;\n }\n return AV.User.__super__._mergeMagicFields.call(this, attrs);\n },\n\n /**\n * Removes null values from authData (which exist temporarily for\n * unlinking)\n * @private\n */\n _cleanupAuthData: function() {\n if (!this.isCurrent()) {\n return;\n }\n var authData = this.get('authData');\n if (!authData) {\n return;\n }\n AV._objectEach(this.get('authData'), function(value, key) {\n if (!authData[key]) {\n delete authData[key];\n }\n });\n },\n\n /**\n * Synchronizes authData for all providers.\n * @private\n */\n _synchronizeAllAuthData: function() {\n var authData = this.get('authData');\n if (!authData) {\n return;\n }\n\n var self = this;\n AV._objectEach(this.get('authData'), function(value, key) {\n self._synchronizeAuthData(key);\n });\n },\n\n /**\n * Synchronizes auth data for a provider (e.g. puts the access token in the\n * right place to be used by the Facebook SDK).\n * @private\n */\n _synchronizeAuthData: function(provider) {\n if (!this.isCurrent()) {\n return;\n }\n var authType;\n if (_.isString(provider)) {\n authType = provider;\n provider = AV.User._authProviders[authType];\n } else {\n authType = provider.getAuthType();\n }\n var authData = this.get('authData');\n if (!authData || !provider) {\n return;\n }\n var success = provider.restoreAuthentication(authData[authType]);\n if (!success) {\n this.dissociateAuthData(provider);\n }\n },\n\n _handleSaveResult: function(makeCurrent) {\n // Clean up and synchronize the authData object, removing any unset values\n if (makeCurrent && !AV._config.disableCurrentUser) {\n this._isCurrentUser = true;\n }\n this._cleanupAuthData();\n this._synchronizeAllAuthData();\n // Don't keep the password around.\n delete this._serverData.password;\n this._rebuildEstimatedDataForKey('password');\n this._refreshCache();\n if (\n (makeCurrent || this.isCurrent()) &&\n !AV._config.disableCurrentUser\n ) {\n // Some old version of leanengine-node-sdk will overwrite\n // AV.User._saveCurrentUser which returns no Promise.\n // So we need a Promise wrapper.\n return Promise.resolve(AV.User._saveCurrentUser(this));\n } else {\n return Promise.resolve();\n }\n },\n\n /**\n * Unlike in the Android/iOS SDKs, logInWith is unnecessary, since you can\n * call linkWith on the user (even if it doesn't exist yet on the server).\n * @private\n */\n _linkWith: function(\n provider,\n data,\n { failOnNotExist = false, useMasterKey, sessionToken, user } = {}\n ) {\n var authType;\n if (_.isString(provider)) {\n authType = provider;\n provider = AV.User._authProviders[provider];\n } else {\n authType = provider.getAuthType();\n }\n if (data) {\n return this.save(\n { authData: { [authType]: data } },\n {\n useMasterKey,\n sessionToken,\n user,\n fetchWhenSave: !!this.get('authData'),\n _failOnNotExist: failOnNotExist,\n }\n ).then(function(model) {\n return model._handleSaveResult(true).then(function() {\n return model;\n });\n });\n } else {\n return provider\n .authenticate()\n .then(result => this._linkWith(provider, result));\n }\n },\n\n /**\n * Associate the user with a third party authData.\n * @since 3.3.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @return {Promisecurrent
.\n *\n * A username and password must be set before calling signUp.
\n *\n * @param {Object} attrs Extra fields to set on the new user, or null.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the signup\n * finishes.\n * @see AV.User.signUp\n */\n signUp: function(attrs, options) {\n var error;\n\n var username = (attrs && attrs.username) || this.get('username');\n if (!username || username === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up user with an empty name.'\n );\n throw error;\n }\n\n var password = (attrs && attrs.password) || this.get('password');\n if (!password || password === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up user with an empty password.'\n );\n throw error;\n }\n\n return this.save(attrs, options).then(function(model) {\n if (model.isAnonymous()) {\n model.unset(`authData.${PLATFORM_ANONYMOUS}`);\n model._opSetQueue = [{}];\n }\n return model._handleSaveResult(true).then(function() {\n return model;\n });\n });\n },\n\n /**\n * Signs up a new user with mobile phone and sms code.\n * You should call this instead of save for\n * new AV.Users. This will create a new AV.User on the server, and\n * also persist the session on disk so that you can access the user using\n *current
.\n *\n * A username and password must be set before calling signUp.
\n *\n * @param {Object} attrs Extra fields to set on the new user, or null.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the signup\n * finishes.\n * @see AV.User.signUpOrlogInWithMobilePhone\n * @see AV.Cloud.requestSmsCode\n */\n signUpOrlogInWithMobilePhone: function(attrs, options = {}) {\n var error;\n\n var mobilePhoneNumber =\n (attrs && attrs.mobilePhoneNumber) || this.get('mobilePhoneNumber');\n if (!mobilePhoneNumber || mobilePhoneNumber === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up or login user by mobilePhoneNumber ' +\n 'with an empty mobilePhoneNumber.'\n );\n throw error;\n }\n\n var smsCode = (attrs && attrs.smsCode) || this.get('smsCode');\n if (!smsCode || smsCode === '') {\n error = new AVError(\n AVError.OTHER_CAUSE,\n 'Cannot sign up or login user by mobilePhoneNumber ' +\n 'with an empty smsCode.'\n );\n throw error;\n }\n\n options._makeRequest = function(route, className, id, method, json) {\n return AVRequest('usersByMobilePhone', null, null, 'POST', json);\n };\n return this.save(attrs, options).then(function(model) {\n delete model.attributes.smsCode;\n delete model._serverData.smsCode;\n return model._handleSaveResult(true).then(function() {\n return model;\n });\n });\n },\n\n /**\n * The same with {@link AV.User.loginWithAuthData}, except that you can set attributes before login.\n * @since 3.7.0\n */\n loginWithAuthData(authData, platform, options) {\n return this._linkWith(platform, authData, options);\n },\n\n /**\n * The same with {@link AV.User.loginWithAuthDataAndUnionId}, except that you can set attributes before login.\n * @since 3.7.0\n */\n loginWithAuthDataAndUnionId(\n authData,\n platform,\n unionId,\n unionLoginOptions\n ) {\n return this.loginWithAuthData(\n mergeUnionDataIntoAuthData()(authData, unionId, unionLoginOptions),\n platform,\n unionLoginOptions\n );\n },\n\n /**\n * The same with {@link AV.User.loginWithWeapp}, except that you can set attributes before login.\n * @deprecated please use {@link AV.User#loginWithMiniApp}\n * @since 3.7.0\n * @param {Object} [options]\n * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @param {boolean} [options.preferUnionId] 当用户满足 {@link https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html 获取 UnionId 的条件} 时,是否使用 UnionId 登录。(since 3.13.0)\n * @param {string} [options.unionIdPlatform = 'weixin'] (only take effect when preferUnionId) unionId platform\n * @param {boolean} [options.asMainAccount = true] (only take effect when preferUnionId) If true, the unionId will be associated with the user.\n * @return {Promisecurrent
.\n *\n * A username and password must be set before calling logIn.
\n *\n * @see AV.User.logIn\n * @return {Promise} A promise that is fulfilled with the user when\n * the login is complete.\n */\n logIn: function() {\n var model = this;\n var request = AVRequest('login', null, null, 'POST', this.toJSON());\n return request.then(function(resp) {\n var serverAttrs = model.parse(resp);\n model._finishFetch(serverAttrs);\n return model._handleSaveResult(true).then(function() {\n if (!serverAttrs.smsCode) delete model.attributes['smsCode'];\n return model;\n });\n });\n },\n /**\n * @see AV.Object#save\n */\n save: function(arg1, arg2, arg3) {\n var attrs, options;\n if (_.isObject(arg1) || _.isNull(arg1) || _.isUndefined(arg1)) {\n attrs = arg1;\n options = arg2;\n } else {\n attrs = {};\n attrs[arg1] = arg2;\n options = arg3;\n }\n options = options || {};\n\n return AV.Object.prototype.save\n .call(this, attrs, options)\n .then(function(model) {\n return model._handleSaveResult(false).then(function() {\n return model;\n });\n });\n },\n\n /**\n * Follow a user\n * @since 0.3.0\n * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user.\n * @param {AV.User | String} options.user The target user or user's objectId to follow.\n * @param {Object} [options.attributes] key-value attributes dictionary to be used as\n * conditions of followerQuery/followeeQuery.\n * @param {AuthOptions} [authOptions]\n */\n follow: function(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n let user;\n let attributes;\n if (options.user) {\n user = options.user;\n attributes = options.attributes;\n } else {\n user = options;\n }\n var userObjectId = _.isString(user) ? user : user.id;\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n var route = 'users/' + this.id + '/friendship/' + userObjectId;\n var request = AVRequest(\n route,\n null,\n null,\n 'POST',\n AV._encode(attributes),\n authOptions\n );\n return request;\n },\n\n /**\n * Unfollow a user.\n * @since 0.3.0\n * @param {Object | AV.User | String} options if an AV.User or string is given, it will be used as the target user.\n * @param {AV.User | String} options.user The target user or user's objectId to unfollow.\n * @param {AuthOptions} [authOptions]\n */\n unfollow: function(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n let user;\n if (options.user) {\n user = options.user;\n } else {\n user = options;\n }\n var userObjectId = _.isString(user) ? user : user.id;\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n var route = 'users/' + this.id + '/friendship/' + userObjectId;\n var request = AVRequest(route, null, null, 'DELETE', null, authOptions);\n return request;\n },\n\n /**\n * Get the user's followers and followees.\n * @since 4.8.0\n * @param {Object} [options]\n * @param {Number} [options.skip]\n * @param {Number} [options.limit]\n * @param {AuthOptions} [authOptions]\n */\n getFollowersAndFollowees: function(options, authOptions) {\n if (!this.id) {\n throw new Error('Please signin.');\n }\n return request({\n method: 'GET',\n path: `/users/${this.id}/followersAndFollowees`,\n query: {\n skip: options && options.skip,\n limit: options && options.limit,\n include: 'follower,followee',\n keys: 'follower,followee',\n },\n authOptions,\n }).then(({ followers, followees }) => ({\n followers: followers.map(({ follower }) => AV._decode(follower)),\n followees: followees.map(({ followee }) => AV._decode(followee)),\n }));\n },\n\n /**\n *Create a follower query to query the user's followers.\n * @since 0.3.0\n * @see AV.User#followerQuery\n */\n followerQuery: function() {\n return AV.User.followerQuery(this.id);\n },\n\n /**\n *Create a followee query to query the user's followees.\n * @since 0.3.0\n * @see AV.User#followeeQuery\n */\n followeeQuery: function() {\n return AV.User.followeeQuery(this.id);\n },\n\n /**\n * @see AV.Object#fetch\n */\n fetch: function(fetchOptions, options) {\n return AV.Object.prototype.fetch\n .call(this, fetchOptions, options)\n .then(function(model) {\n return model._handleSaveResult(false).then(function() {\n return model;\n });\n });\n },\n\n /**\n * Update user's new password safely based on old password.\n * @param {String} oldPassword the old password.\n * @param {String} newPassword the new password.\n * @param {AuthOptions} options\n */\n updatePassword: function(oldPassword, newPassword, options) {\n var route = 'users/' + this.id + '/updatePassword';\n var params = {\n old_password: oldPassword,\n new_password: newPassword,\n };\n var request = AVRequest(route, null, null, 'PUT', params, options);\n return request.then(resp => {\n this._finishFetch(this.parse(resp));\n return this._handleSaveResult(true).then(() => resp);\n });\n },\n\n /**\n * Returns true ifcurrent
would return this user.\n * @see AV.User#current\n */\n isCurrent: function() {\n return this._isCurrentUser;\n },\n\n /**\n * Returns get(\"username\").\n * @return {String}\n * @see AV.Object#get\n */\n getUsername: function() {\n return this.get('username');\n },\n\n /**\n * Returns get(\"mobilePhoneNumber\").\n * @return {String}\n * @see AV.Object#get\n */\n getMobilePhoneNumber: function() {\n return this.get('mobilePhoneNumber');\n },\n\n /**\n * Calls set(\"mobilePhoneNumber\", phoneNumber, options) and returns the result.\n * @param {String} mobilePhoneNumber\n * @return {Boolean}\n * @see AV.Object#set\n */\n setMobilePhoneNumber: function(phone, options) {\n return this.set('mobilePhoneNumber', phone, options);\n },\n\n /**\n * Calls set(\"username\", username, options) and returns the result.\n * @param {String} username\n * @return {Boolean}\n * @see AV.Object#set\n */\n setUsername: function(username, options) {\n return this.set('username', username, options);\n },\n\n /**\n * Calls set(\"password\", password, options) and returns the result.\n * @param {String} password\n * @return {Boolean}\n * @see AV.Object#set\n */\n setPassword: function(password, options) {\n return this.set('password', password, options);\n },\n\n /**\n * Returns get(\"email\").\n * @return {String}\n * @see AV.Object#get\n */\n getEmail: function() {\n return this.get('email');\n },\n\n /**\n * Calls set(\"email\", email, options) and returns the result.\n * @param {String} email\n * @param {AuthOptions} options\n * @return {Boolean}\n * @see AV.Object#set\n */\n setEmail: function(email, options) {\n return this.set('email', email, options);\n },\n\n /**\n * Checks whether this user is the current user and has been authenticated.\n * @deprecated 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),\n * 如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id\n * @return (Boolean) whether this user is the current user and is logged in.\n */\n authenticated: function() {\n console.warn(\n 'DEPRECATED: 如果要判断当前用户的登录状态是否有效,请使用 currentUser.isAuthenticated().then(),如果要判断该用户是否是当前登录用户,请使用 user.id === currentUser.id。'\n );\n return (\n !!this._sessionToken &&\n (!AV._config.disableCurrentUser &&\n AV.User.current() &&\n AV.User.current().id === this.id)\n );\n },\n\n /**\n * Detects if current sessionToken is valid.\n *\n * @since 2.0.0\n * @return Promise.current
.\n *\n * @param {String} username The username (or email) to log in with.\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logIn: function(username, password) {\n var user = AV.Object._create('_User');\n user._finishFetch({ username: username, password: password });\n return user.logIn();\n },\n\n /**\n * Logs in a user with a session token. On success, this saves the session\n * to disk, so you can retrieve the currently logged in user using\n * current
.\n *\n * @param {String} sessionToken The sessionToken to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n */\n become: function(sessionToken) {\n return this._fetchUserBySessionToken(sessionToken).then(user =>\n user._handleSaveResult(true).then(() => user)\n );\n },\n\n _fetchUserBySessionToken: function(sessionToken) {\n if (sessionToken === undefined) {\n return Promise.reject(\n new Error('The sessionToken cannot be undefined')\n );\n }\n\n var user = AV.Object._create('_User');\n return request({\n method: 'GET',\n path: '/users/me',\n authOptions: {\n sessionToken,\n },\n }).then(function(resp) {\n var serverAttrs = user.parse(resp);\n user._finishFetch(serverAttrs);\n return user;\n });\n },\n\n /**\n * Logs in a user with a mobile phone number and sms code sent by\n * AV.User.requestLoginSmsCode.On success, this\n * saves the session to disk, so you can retrieve the currently logged in\n * user using current
.\n *\n * @param {String} mobilePhone The user's mobilePhoneNumber\n * @param {String} smsCode The sms code sent by AV.User.requestLoginSmsCode\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logInWithMobilePhoneSmsCode: function(mobilePhone, smsCode) {\n var user = AV.Object._create('_User');\n user._finishFetch({ mobilePhoneNumber: mobilePhone, smsCode: smsCode });\n return user.logIn();\n },\n\n /**\n * Signs up or logs in a user with a mobilePhoneNumber and smsCode.\n * On success, this saves the session to disk, so you can retrieve the currently\n * logged in user using current
.\n *\n * @param {String} mobilePhoneNumber The user's mobilePhoneNumber.\n * @param {String} smsCode The sms code sent by AV.Cloud.requestSmsCode\n * @param {Object} attributes The user's other attributes such as username etc.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#signUpOrlogInWithMobilePhone\n * @see AV.Cloud.requestSmsCode\n */\n signUpOrlogInWithMobilePhone: function(\n mobilePhoneNumber,\n smsCode,\n attrs,\n options\n ) {\n attrs = attrs || {};\n attrs.mobilePhoneNumber = mobilePhoneNumber;\n attrs.smsCode = smsCode;\n var user = AV.Object._create('_User');\n return user.signUpOrlogInWithMobilePhone(attrs, options);\n },\n\n /**\n * Logs in a user with a mobile phone number and password. On success, this\n * saves the session to disk, so you can retrieve the currently logged in\n * user using current
.\n *\n * @param {String} mobilePhone The user's mobilePhoneNumber\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @see AV.User#logIn\n */\n logInWithMobilePhone: function(mobilePhone, password) {\n var user = AV.Object._create('_User');\n user._finishFetch({\n mobilePhoneNumber: mobilePhone,\n password: password,\n });\n return user.logIn();\n },\n\n /**\n * Logs in a user with email and password.\n *\n * @since 3.13.0\n * @param {String} email The user's email.\n * @param {String} password The password to log in with.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n */\n loginWithEmail(email, password) {\n const user = AV.Object._create('_User');\n user._finishFetch({\n email,\n password,\n });\n return user.logIn();\n },\n\n /**\n * Signs up or logs in a user with a third party auth data(AccessToken).\n * On success, this saves the session to disk, so you can retrieve the currently\n * logged in user using current
.\n *\n * @since 3.7.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @param {Object} [options]\n * @param {boolean} [options.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @return {Promise} A promise that is fulfilled with the user when\n * the login completes.\n * @example AV.User.loginWithAuthData({\n * openid: 'abc123',\n * access_token: '123abc',\n * expires_in: 1382686496\n * }, 'weixin').then(function(user) {\n * //Access user here\n * }).catch(function(error) {\n * //console.error(\"error: \", error);\n * });\n * @see {@link https://leancloud.cn/docs/js_guide.html#绑定第三方平台账户}\n */\n loginWithAuthData(authData, platform, options) {\n return AV.User._logInWith(platform, authData, options);\n },\n\n /**\n * @deprecated renamed to {@link AV.User.loginWithAuthData}\n */\n signUpOrlogInWithAuthData(...param) {\n console.warn(\n 'DEPRECATED: User.signUpOrlogInWithAuthData 已废弃,请使用 User#loginWithAuthData 代替'\n );\n return this.loginWithAuthData(...param);\n },\n\n /**\n * Signs up or logs in a user with a third party authData and unionId.\n * @since 3.7.0\n * @param {Object} authData The response json data returned from third party token, maybe like { openid: 'abc123', access_token: '123abc', expires_in: 1382686496 }\n * @param {string} platform Available platform for sign up.\n * @param {string} unionId\n * @param {Object} [unionLoginOptions]\n * @param {string} [unionLoginOptions.unionIdPlatform = 'weixin'] unionId platform\n * @param {boolean} [unionLoginOptions.asMainAccount = false] If true, the unionId will be associated with the user.\n * @param {boolean} [unionLoginOptions.failOnNotExist] If true, the login request will fail when no user matches this authData exists.\n * @return {Promisecurrent
will return null
.\n * @return {Promise}\n */\n logOut: function() {\n if (AV._config.disableCurrentUser) {\n console.warn(\n 'AV.User.current() was disabled in multi-user environment, call logOut() from user object instead https://leancloud.cn/docs/leanengine-node-sdk-upgrade-1.html'\n );\n return Promise.resolve(null);\n }\n\n if (AV.User._currentUser !== null) {\n AV.User._currentUser._logOutWithAll();\n AV.User._currentUser._isCurrentUser = false;\n }\n AV.User._currentUserMatchesDisk = true;\n AV.User._currentUser = null;\n return AV.localStorage\n .removeItemAsync(AV._getAVPath(AV.User._CURRENT_USER_KEY))\n .then(() => AV._refreshSubscriptionId());\n },\n\n /**\n *Create a follower query for special user to query the user's followers.\n * @param {String} userObjectId The user object id.\n * @return {AV.FriendShipQuery}\n * @since 0.3.0\n */\n followerQuery: function(userObjectId) {\n if (!userObjectId || !_.isString(userObjectId)) {\n throw new Error('Invalid user object id.');\n }\n var query = new AV.FriendShipQuery('_Follower');\n query._friendshipTag = 'follower';\n query.equalTo(\n 'user',\n AV.Object.createWithoutData('_User', userObjectId)\n );\n return query;\n },\n\n /**\n *Create a followee query for special user to query the user's followees.\n * @param {String} userObjectId The user object id.\n * @return {AV.FriendShipQuery}\n * @since 0.3.0\n */\n followeeQuery: function(userObjectId) {\n if (!userObjectId || !_.isString(userObjectId)) {\n throw new Error('Invalid user object id.');\n }\n var query = new AV.FriendShipQuery('_Followee');\n query._friendshipTag = 'followee';\n query.equalTo(\n 'user',\n AV.Object.createWithoutData('_User', userObjectId)\n );\n return query;\n },\n\n /**\n * Requests a password reset email to be sent to the specified email address\n * associated with the user account. This email allows the user to securely\n * reset their password on the AV site.\n *\n * @param {String} email The email address associated with the user that\n * forgot their password.\n * @return {Promise}\n */\n requestPasswordReset: function(email) {\n var json = { email: email };\n var request = AVRequest(\n 'requestPasswordReset',\n null,\n null,\n 'POST',\n json\n );\n return request;\n },\n\n /**\n * Requests a verify email to be sent to the specified email address\n * associated with the user account. This email allows the user to securely\n * verify their email address on the AV site.\n *\n * @param {String} email The email address associated with the user that\n * doesn't verify their email address.\n * @return {Promise}\n */\n requestEmailVerify: function(email) {\n var json = { email: email };\n var request = AVRequest('requestEmailVerify', null, null, 'POST', json);\n return request;\n },\n\n /**\n * Requests a verify sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * verify their mobile phone number by calling AV.User.verifyMobilePhone\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that doesn't verify their mobile phone number.\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestMobilePhoneVerify: function(mobilePhoneNumber, options = {}) {\n const data = {\n mobilePhoneNumber,\n };\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n var request = AVRequest(\n 'requestMobilePhoneVerify',\n null,\n null,\n 'POST',\n data,\n options\n );\n return request;\n },\n\n /**\n * Requests a reset password sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * reset their account's password by calling AV.User.resetPasswordBySmsCode\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that doesn't verify their mobile phone number.\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestPasswordResetBySmsCode: function(mobilePhoneNumber, options = {}) {\n const data = {\n mobilePhoneNumber,\n };\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n var request = AVRequest(\n 'requestPasswordResetBySmsCode',\n null,\n null,\n 'POST',\n data,\n options\n );\n return request;\n },\n\n /**\n * Requests a change mobile phone number sms code to be sent to the mobilePhoneNumber.\n * This sms code allows current user to reset it's mobilePhoneNumber by\n * calling {@link AV.User.changePhoneNumber}\n * @since 4.7.0\n * @param {String} mobilePhoneNumber\n * @param {Number} [ttl] ttl of sms code (default is 6 minutes)\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestChangePhoneNumber(mobilePhoneNumber, ttl, options) {\n const data = { mobilePhoneNumber };\n if (ttl) {\n data.ttl = options.ttl;\n }\n if (options && options.validateToken) {\n data.validate_token = options.validateToken;\n }\n return AVRequest(\n 'requestChangePhoneNumber',\n null,\n null,\n 'POST',\n data,\n options\n );\n },\n\n /**\n * Makes a call to reset user's account mobilePhoneNumber by sms code.\n * The sms code is sent by {@link AV.User.requestChangePhoneNumber}\n * @since 4.7.0\n * @param {String} mobilePhoneNumber\n * @param {String} code The sms code.\n * @return {Promise}\n */\n changePhoneNumber(mobilePhoneNumber, code) {\n const data = { mobilePhoneNumber, code };\n return AVRequest('changePhoneNumber', null, null, 'POST', data);\n },\n\n /**\n * Makes a call to reset user's account password by sms code and new password.\n * The sms code is sent by AV.User.requestPasswordResetBySmsCode.\n * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode\n * @param {String} password The new password.\n * @param {String} mobilePhoneNumber\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n resetPasswordBySmsCode: function(code, password, mobilePhoneNumber) {\n var json = { password: password, mobilePhoneNumber: mobilePhoneNumber };\n var request = AVRequest(\n 'resetPasswordBySmsCode',\n null,\n code,\n 'PUT',\n json\n );\n return request;\n },\n\n /**\n * Makes a call to verify sms code that sent by AV.User.Cloud.requestSmsCode\n * If verify successfully,the user mobilePhoneVerified attribute will be true.\n * @param {String} code The sms code sent by AV.User.Cloud.requestSmsCode\n * @param {String} mobilePhoneNumber\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n verifyMobilePhone: function(code, mobilePhoneNumber) {\n var json = { mobilePhoneNumber: mobilePhoneNumber };\n var request = AVRequest('verifyMobilePhone', null, code, 'POST', json);\n return request;\n },\n\n /**\n * Requests a logIn sms code to be sent to the specified mobile phone\n * number associated with the user account. This sms code allows the user to\n * login by AV.User.logInWithMobilePhoneSmsCode function.\n *\n * @param {String} mobilePhoneNumber The mobile phone number associated with the\n * user that want to login by AV.User.logInWithMobilePhoneSmsCode\n * @param {SMSAuthOptions} [options]\n * @return {Promise}\n */\n requestLoginSmsCode: function(mobilePhoneNumber, options = {}) {\n const data = {\n mobilePhoneNumber,\n };\n if (options.validateToken) {\n data.validate_token = options.validateToken;\n }\n var request = AVRequest(\n 'requestLoginSmsCode',\n null,\n null,\n 'POST',\n data,\n options\n );\n return request;\n },\n\n /**\n * Retrieves the currently logged in AVUser with a valid session,\n * either from memory or localStorage, if necessary.\n * @return {Promise.AV.Query defines a query that is used to fetch AV.Objects. The\n * most common use case is finding all objects that match a query through the\n * find
method. For example, this sample code fetches all objects\n * of class MyClass
. It calls a different function depending on\n * whether the fetch succeeded or not.\n *\n *
\n * var query = new AV.Query(MyClass);\n * query.find().then(function(results) {\n * // results is an array of AV.Object.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n *\n *
An AV.Query can also be used to retrieve a single object whose id is\n * known, through the get method. For example, this sample code fetches an\n * object of class MyClass
and id myId
. It calls a\n * different function depending on whether the fetch succeeded or not.\n *\n *
\n * var query = new AV.Query(MyClass);\n * query.get(myId).then(function(object) {\n * // object is an instance of AV.Object.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n *\n *
An AV.Query can also be used to count the number of objects that match\n * the query without retrieving all of those objects. For example, this\n * sample code counts the number of objects of the class MyClass
\n *
\n * var query = new AV.Query(MyClass);\n * query.count().then(function(number) {\n * // There are number instances of MyClass.\n * }, function(error) {\n * // error is an instance of AVError.\n * });\n */\n AV.Query = function(objectClass) {\n if (_.isString(objectClass)) {\n objectClass = AV.Object._getSubclass(objectClass);\n }\n\n this.objectClass = objectClass;\n\n this.className = objectClass.prototype.className;\n\n this._where = {};\n this._include = [];\n this._select = [];\n this._limit = -1; // negative limit means, do not send a limit\n this._skip = 0;\n this._defaultParams = {};\n };\n\n /**\n * Constructs a AV.Query that is the OR of the passed in queries. For\n * example:\n *
var compoundQuery = AV.Query.or(query1, query2, query3);\n *\n * will create a compoundQuery that is an or of the query1, query2, and\n * query3.\n * @param {...AV.Query} var_args The list of queries to OR.\n * @return {AV.Query} The query that is the OR of the passed in queries.\n */\n AV.Query.or = function() {\n var queries = _.toArray(arguments);\n var className = null;\n AV._arrayEach(queries, function(q) {\n if (_.isNull(className)) {\n className = q.className;\n }\n\n if (className !== q.className) {\n throw new Error('All queries must be for the same class');\n }\n });\n var query = new AV.Query(className);\n query._orQuery(queries);\n return query;\n };\n\n /**\n * Constructs a AV.Query that is the AND of the passed in queries. For\n * example:\n *
var compoundQuery = AV.Query.and(query1, query2, query3);\n *\n * will create a compoundQuery that is an 'and' of the query1, query2, and\n * query3.\n * @param {...AV.Query} var_args The list of queries to AND.\n * @return {AV.Query} The query that is the AND of the passed in queries.\n */\n AV.Query.and = function() {\n var queries = _.toArray(arguments);\n var className = null;\n AV._arrayEach(queries, function(q) {\n if (_.isNull(className)) {\n className = q.className;\n }\n\n if (className !== q.className) {\n throw new Error('All queries must be for the same class');\n }\n });\n var query = new AV.Query(className);\n query._andQuery(queries);\n return query;\n };\n\n /**\n * Retrieves a list of AVObjects that satisfy the CQL.\n * CQL syntax please see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.\n *\n * @param {String} cql A CQL string, see {@link https://leancloud.cn/docs/cql_guide.html CQL Guide}.\n * @param {Array} pvalues An array contains placeholder values.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is resolved with the results when\n * the query completes.\n */\n AV.Query.doCloudQuery = function(cql, pvalues, options) {\n var params = { cql: cql };\n if (_.isArray(pvalues)) {\n params.pvalues = pvalues;\n } else {\n options = pvalues;\n }\n\n var request = _request('cloudQuery', null, null, 'GET', params, options);\n return request.then(function(response) {\n //query to process results.\n var query = new AV.Query(response.className);\n var results = _.map(response.results, function(json) {\n var obj = query._newObject(response);\n if (obj._finishFetch) {\n obj._finishFetch(query._processResult(json), true);\n }\n return obj;\n });\n return {\n results: results,\n count: response.count,\n className: response.className,\n };\n });\n };\n\n /**\n * Return a query with conditions from json.\n * This can be useful to send a query from server side to client side.\n * @since 4.0.0\n * @param {Object} json from {@link AV.Query#toJSON}\n * @return {AV.Query}\n */\n AV.Query.fromJSON = ({\n className,\n where,\n include,\n select,\n includeACL,\n limit,\n skip,\n order,\n }) => {\n if (typeof className !== 'string') {\n throw new TypeError('Invalid Query JSON, className must be a String.');\n }\n const query = new AV.Query(className);\n _.extend(query, {\n _where: where,\n _include: include,\n _select: select,\n _includeACL: includeACL,\n _limit: limit,\n _skip: skip,\n _order: order,\n });\n return query;\n };\n\n AV.Query._extend = AV._extend;\n\n _.extend(\n AV.Query.prototype,\n /** @lends AV.Query.prototype */ {\n //hook to iterate result. Added by dennis
\n * Some functions are only available from Cloud Code.\n *
\n *\n * @namespace\n * @borrows AV.Captcha.request as requestCaptcha\n */\n AV.Cloud = AV.Cloud || {};\n\n _.extend(\n AV.Cloud,\n /** @lends AV.Cloud */ {\n /**\n * Makes a call to a cloud function.\n * @param {String} name The function name.\n * @param {Object} [data] The parameters to send to the cloud function.\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n run(name, data, options) {\n return request({\n service: 'engine',\n method: 'POST',\n path: `/functions/${name}`,\n data: AV._encode(data, null, true),\n authOptions: options,\n }).then(resp => {\n return AV._decode(resp).result;\n });\n },\n\n /**\n * Makes a call to a cloud function, you can send {AV.Object} as param or a field of param; the response\n * from server will also be parsed as an {AV.Object}, array of {AV.Object}, or object includes {AV.Object}\n * @param {String} name The function name.\n * @param {Object} [data] The parameters to send to the cloud function.\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result of the function.\n */\n rpc(name, data, options) {\n if (_.isArray(data)) {\n return Promise.reject(\n new Error(\n \"Can't pass Array as the param of rpc function in JavaScript SDK.\"\n )\n );\n }\n\n return request({\n service: 'engine',\n method: 'POST',\n path: `/call/${name}`,\n data: AV._encodeObjectOrArray(data),\n authOptions: options,\n }).then(resp => {\n return AV._decode(resp).result;\n });\n },\n\n /**\n * Make a call to request server date time.\n * @return {Promise.Send a status from current signined user to other user's private status inbox.
\n * @since 0.3.0\n * @param {AV.Status} status A status object to be send to followers.\n * @param {String} target The target user or user's objectId.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the send\n * completes.\n * @example\n * // send a private status to user '52e84e47e4b0f8de283b079b'\n * var status = new AVStatus('image url', 'a message');\n * AV.Status.sendPrivateStatus(status, '52e84e47e4b0f8de283b079b').then(function(){\n * //send status successfully.\n * }, function(err){\n * //an error threw.\n * console.dir(err);\n * });\n */\n AV.Status.sendPrivateStatus = function(status, target, options = {}) {\n if (!getSessionToken(options) && !AV.User.current()) {\n throw new Error('Please signin an user.');\n }\n if (!target) {\n throw new Error('Invalid target user.');\n }\n var userObjectId = _.isString(target) ? target : target.id;\n if (!userObjectId) {\n throw new Error('Invalid target user.');\n }\n return getUserPointer(options).then(currUser => {\n var query = {};\n query.className = '_User';\n query.where = { objectId: userObjectId };\n var data = {};\n data.query = query;\n status.data = status.data || {};\n status.data.source = status.data.source || currUser;\n data.data = status._getDataJSON();\n data.inboxType = 'private';\n status.inboxType = 'private';\n\n var request = AVRequest('statuses', null, null, 'POST', data, options);\n return request.then(function(response) {\n status.id = response.objectId;\n status.createdAt = AV._parseDate(response.createdAt);\n return status;\n });\n });\n };\n\n /**\n * Count unread statuses in someone's inbox.\n * @since 0.3.0\n * @param {AV.User} owner The status owner.\n * @param {String} inboxType The inbox type, 'default' by default.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the count\n * completes.\n * @example\n * AV.Status.countUnreadStatuses(AV.User.current()).then(function(response){\n * console.log(response.unread); //unread statuses number.\n * console.log(response.total); //total statuses number.\n * });\n */\n AV.Status.countUnreadStatuses = function(\n owner,\n inboxType = 'default',\n options = {}\n ) {\n if (!_.isString(inboxType)) options = inboxType;\n if (!getSessionToken(options) && owner == null && !AV.User.current()) {\n throw new Error('Please signin an user or pass the owner objectId.');\n }\n return Promise.resolve(owner || getUser(options)).then(owner => {\n var params = {};\n params.inboxType = AV._encode(inboxType);\n params.owner = AV._encode(owner);\n return AVRequest(\n 'subscribe/statuses/count',\n null,\n null,\n 'GET',\n params,\n options\n );\n });\n };\n\n /**\n * reset unread statuses count in someone's inbox.\n * @since 2.1.0\n * @param {AV.User} owner The status owner.\n * @param {String} inboxType The inbox type, 'default' by default.\n * @param {AuthOptions} options\n * @return {Promise} A promise that is fulfilled when the reset\n * completes.\n * @example\n * AV.Status.resetUnreadCount(AV.User.current()).then(function(response){\n * console.log(response.unread); //unread statuses number.\n * console.log(response.total); //total statuses number.\n * });\n */\n AV.Status.resetUnreadCount = function(\n owner,\n inboxType = 'default',\n options = {}\n ) {\n if (!_.isString(inboxType)) options = inboxType;\n if (!getSessionToken(options) && owner == null && !AV.User.current()) {\n throw new Error('Please signin an user or pass the owner objectId.');\n }\n return Promise.resolve(owner || getUser(options)).then(owner => {\n var params = {};\n params.inboxType = AV._encode(inboxType);\n params.owner = AV._encode(owner);\n return AVRequest(\n 'subscribe/statuses/resetUnreadCount',\n null,\n null,\n 'POST',\n params,\n options\n );\n });\n };\n\n /**\n * Create a status query to find someone's published statuses.\n * @since 0.3.0\n * @param {AV.User} source The status source, typically the publisher.\n * @return {AV.Query} The query object for status.\n * @example\n * //Find current user's published statuses.\n * var query = AV.Status.statusQuery(AV.User.current());\n * query.find().then(function(statuses){\n * //process statuses\n * });\n */\n AV.Status.statusQuery = function(source) {\n var query = new AV.Query('_Status');\n if (source) {\n query.equalTo('source', source);\n }\n return query;\n };\n\n /**\n *AV.InboxQuery defines a query that is used to fetch somebody's inbox statuses.
\n * @class\n */\n AV.InboxQuery = AV.Query._extend(\n /** @lends AV.InboxQuery.prototype */ {\n _objectClass: AV.Status,\n _sinceId: 0,\n _maxId: 0,\n _inboxType: 'default',\n _owner: null,\n _newObject: function() {\n return new AV.Status();\n },\n _createRequest: function(params, options) {\n return AV.InboxQuery.__super__._createRequest.call(\n this,\n params,\n options,\n '/subscribe/statuses'\n );\n },\n\n /**\n * Sets the messageId of results to skip before returning any results.\n * This is useful for pagination.\n * Default is zero.\n * @param {Number} n the mesage id.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n sinceId: function(id) {\n this._sinceId = id;\n return this;\n },\n /**\n * Sets the maximal messageId of results。\n * This is useful for pagination.\n * Default is zero that is no limition.\n * @param {Number} n the mesage id.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n maxId: function(id) {\n this._maxId = id;\n return this;\n },\n /**\n * Sets the owner of the querying inbox.\n * @param {AV.User} owner The inbox owner.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n owner: function(owner) {\n this._owner = owner;\n return this;\n },\n /**\n * Sets the querying inbox type.default is 'default'.\n * @param {String} type The inbox type.\n * @return {AV.InboxQuery} Returns the query, so you can chain this call.\n */\n inboxType: function(type) {\n this._inboxType = type;\n return this;\n },\n _getParams: function() {\n var params = AV.InboxQuery.__super__._getParams.call(this);\n params.owner = AV._encode(this._owner);\n params.inboxType = AV._encode(this._inboxType);\n params.sinceId = AV._encode(this._sinceId);\n params.maxId = AV._encode(this._maxId);\n return params;\n },\n }\n );\n\n /**\n * Create a inbox status query to find someone's inbox statuses.\n * @since 0.3.0\n * @param {AV.User} owner The inbox's owner\n * @param {String} inboxType The inbox type,'default' by default.\n * @return {AV.InboxQuery} The inbox query object.\n * @see AV.InboxQuery\n * @example\n * //Find current user's default inbox statuses.\n * var query = AV.Status.inboxQuery(AV.User.current());\n * //find the statuses after the last message id\n * query.sinceId(lastMessageId);\n * query.find().then(function(statuses){\n * //process statuses\n * });\n */\n AV.Status.inboxQuery = function(owner, inboxType) {\n var query = new AV.InboxQuery(AV.Status);\n if (owner) {\n query._owner = owner;\n }\n if (inboxType) {\n query._inboxType = inboxType;\n }\n return query;\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/status.js","const _ = require('underscore');\nconst AVRequest = require('./request')._request;\n\nmodule.exports = function(AV) {\n /**\n * A builder to generate sort string for app searching.For example:\n * @class\n * @since 0.5.1\n * @example\n * var builder = new AV.SearchSortBuilder();\n * builder.ascending('key1').descending('key2','max');\n * var query = new AV.SearchQuery('Player');\n * query.sortBy(builder);\n * query.find().then();\n */\n AV.SearchSortBuilder = function() {\n this._sortFields = [];\n };\n\n _.extend(\n AV.SearchSortBuilder.prototype,\n /** @lends AV.SearchSortBuilder.prototype */ {\n _addField: function(key, order, mode, missing) {\n var field = {};\n field[key] = {\n order: order || 'asc',\n mode: mode || 'avg',\n missing: '_' + (missing || 'last'),\n };\n this._sortFields.push(field);\n return this;\n },\n\n /**\n * Sorts the results in ascending order by the given key and options.\n *\n * @param {String} key The key to order by.\n * @param {String} mode The sort mode, default is 'avg', you can choose\n * 'max' or 'min' too.\n * @param {String} missing The missing key behaviour, default is 'last',\n * you can choose 'first' too.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n ascending: function(key, mode, missing) {\n return this._addField(key, 'asc', mode, missing);\n },\n\n /**\n * Sorts the results in descending order by the given key and options.\n *\n * @param {String} key The key to order by.\n * @param {String} mode The sort mode, default is 'avg', you can choose\n * 'max' or 'min' too.\n * @param {String} missing The missing key behaviour, default is 'last',\n * you can choose 'first' too.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n descending: function(key, mode, missing) {\n return this._addField(key, 'desc', mode, missing);\n },\n\n /**\n * Add a proximity based constraint for finding objects with key point\n * values near the point given.\n * @param {String} key The key that the AV.GeoPoint is stored in.\n * @param {AV.GeoPoint} point The reference AV.GeoPoint that is used.\n * @param {Object} options The other options such as mode,order, unit etc.\n * @return {AV.SearchSortBuilder} Returns the builder, so you can chain this call.\n */\n whereNear: function(key, point, options) {\n options = options || {};\n var field = {};\n var geo = {\n lat: point.latitude,\n lon: point.longitude,\n };\n var m = {\n order: options.order || 'asc',\n mode: options.mode || 'avg',\n unit: options.unit || 'km',\n };\n m[key] = geo;\n field['_geo_distance'] = m;\n\n this._sortFields.push(field);\n return this;\n },\n\n /**\n * Build a sort string by configuration.\n * @return {String} the sort string.\n */\n build: function() {\n return JSON.stringify(AV._encode(this._sortFields));\n },\n }\n );\n\n /**\n * App searching query.Use just like AV.Query:\n *\n * Visit App Searching Guide\n * for more details.\n * @class\n * @since 0.5.1\n * @example\n * var query = new AV.SearchQuery('Player');\n * query.queryString('*');\n * query.find().then(function(results) {\n * console.log('Found %d objects', query.hits());\n * //Process results\n * });\n */\n AV.SearchQuery = AV.Query._extend(\n /** @lends AV.SearchQuery.prototype */ {\n _sid: null,\n _hits: 0,\n _queryString: null,\n _highlights: null,\n _sortBuilder: null,\n _clazz: null,\n\n constructor: function(className) {\n if (className) {\n this._clazz = className;\n } else {\n className = '__INVALID_CLASS';\n }\n AV.Query.call(this, className);\n },\n\n _createRequest: function(params, options) {\n return AVRequest(\n 'search/select',\n null,\n null,\n 'GET',\n params || this._getParams(),\n options\n );\n },\n\n /**\n * Sets the sid of app searching query.Default is null.\n * @param {String} sid Scroll id for searching.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n sid: function(sid) {\n this._sid = sid;\n return this;\n },\n\n /**\n * Sets the query string of app searching.\n * @param {String} q The query string.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n queryString: function(q) {\n this._queryString = q;\n return this;\n },\n\n /**\n * Sets the highlight fields. Such as\n *\n * query.highlights('title');\n * //or pass an array.\n * query.highlights(['title', 'content'])\n *
\n * @param {String|String[]} highlights a list of fields.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n highlights: function(highlights) {\n var objects;\n if (highlights && _.isString(highlights)) {\n objects = _.toArray(arguments);\n } else {\n objects = highlights;\n }\n this._highlights = objects;\n return this;\n },\n\n /**\n * Sets the sort builder for this query.\n * @see AV.SearchSortBuilder\n * @param { AV.SearchSortBuilder} builder The sort builder.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n *\n */\n sortBy: function(builder) {\n this._sortBuilder = builder;\n return this;\n },\n\n /**\n * Returns the number of objects that match this query.\n * @return {Number}\n */\n hits: function() {\n if (!this._hits) {\n this._hits = 0;\n }\n return this._hits;\n },\n\n _processResult: function(json) {\n delete json['className'];\n delete json['_app_url'];\n delete json['_deeplink'];\n return json;\n },\n\n /**\n * Returns true when there are more documents can be retrieved by this\n * query instance, you can call find function to get more results.\n * @see AV.SearchQuery#find\n * @return {Boolean}\n */\n hasMore: function() {\n return !this._hitEnd;\n },\n\n /**\n * Reset current query instance state(such as sid, hits etc) except params\n * for a new searching. After resetting, hasMore() will return true.\n */\n reset: function() {\n this._hitEnd = false;\n this._sid = null;\n this._hits = 0;\n },\n\n /**\n * Retrieves a list of AVObjects that satisfy this query.\n * Either options.success or options.error is called when the find\n * completes.\n *\n * @see AV.Query#find\n * @param {AuthOptions} options\n * @return {Promise} A promise that is resolved with the results when\n * the query completes.\n */\n find: function(options) {\n var self = this;\n\n var request = this._createRequest(undefined, options);\n\n return request.then(function(response) {\n //update sid for next querying.\n if (response.sid) {\n self._oldSid = self._sid;\n self._sid = response.sid;\n } else {\n self._sid = null;\n self._hitEnd = true;\n }\n self._hits = response.hits || 0;\n\n return _.map(response.results, function(json) {\n if (json.className) {\n response.className = json.className;\n }\n var obj = self._newObject(response);\n obj.appURL = json['_app_url'];\n obj._finishFetch(self._processResult(json), true);\n return obj;\n });\n });\n },\n\n _getParams: function() {\n var params = AV.SearchQuery.__super__._getParams.call(this);\n delete params.where;\n if (this._clazz) {\n params.clazz = this.className;\n }\n if (this._sid) {\n params.sid = this._sid;\n }\n if (!this._queryString) {\n throw new Error('Please set query string.');\n } else {\n params.q = this._queryString;\n }\n if (this._highlights) {\n params.highlights = this._highlights.join(',');\n }\n if (this._sortBuilder && params.order) {\n throw new Error('sort and order can not be set at same time.');\n }\n if (this._sortBuilder) {\n params.sort = this._sortBuilder.build();\n }\n\n return params;\n },\n }\n );\n};\n\n/**\n * Sorts the results in ascending order by the given key.\n *\n * @method AV.SearchQuery#ascending\n * @param {String} key The key to order by.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Also sorts the results in ascending order by the given key. The previous sort keys have\n * precedence over this key.\n *\n * @method AV.SearchQuery#addAscending\n * @param {String} key The key to order by\n * @return {AV.SearchQuery} Returns the query so you can chain this call.\n */\n/**\n * Sorts the results in descending order by the given key.\n *\n * @method AV.SearchQuery#descending\n * @param {String} key The key to order by.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Also sorts the results in descending order by the given key. The previous sort keys have\n * precedence over this key.\n *\n * @method AV.SearchQuery#addDescending\n * @param {String} key The key to order by\n * @return {AV.SearchQuery} Returns the query so you can chain this call.\n */\n/**\n * Include nested AV.Objects for the provided key. You can use dot\n * notation to specify which fields in the included object are also fetch.\n * @method AV.SearchQuery#include\n * @param {String[]} keys The name of the key to include.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Sets the number of results to skip before returning any results.\n * This is useful for pagination.\n * Default is to skip zero results.\n * @method AV.SearchQuery#skip\n * @param {Number} n the number of results to skip.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n/**\n * Sets the limit of the number of results to return. The default limit is\n * 100, with a maximum of 1000 results being returned at a time.\n * @method AV.SearchQuery#limit\n * @param {Number} n the number of results to limit to.\n * @return {AV.SearchQuery} Returns the query, so you can chain this call.\n */\n\n\n\n// WEBPACK FOOTER //\n// ./src/search.js","const _ = require('underscore');\nconst AVError = require('./error');\nconst { request } = require('./request');\n\nmodule.exports = function(AV) {\n /**\n * 包含了使用了 LeanCloud\n * 离线数据分析功能的函数。\n * \n * 仅在云引擎运行环境下有效。\n *
\n * @namespace\n */\n AV.Insight = AV.Insight || {};\n\n _.extend(\n AV.Insight,\n /** @lends AV.Insight */ {\n /**\n * 开始一个 Insight 任务。结果里将返回 Job id,你可以拿得到的 id 使用\n * AV.Insight.JobQuery 查询任务状态和结果。\n * @param {Object} jobConfig 任务配置的 JSON 对象,例如:\n * { \"sql\" : \"select count(*) as c,gender from _User group by gender\",\n * \"saveAs\": {\n * \"className\" : \"UserGender\",\n * \"limit\": 1\n * }\n * }\n *
\n * sql 指定任务执行的 SQL 语句, saveAs(可选) 指定将结果保存在哪张表里,limit 最大 1000。\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n */\n startJob: function(jobConfig, options) {\n if (!jobConfig || !jobConfig.sql) {\n throw new Error('Please provide the sql to run the job.');\n }\n var data = {\n jobConfig: jobConfig,\n appId: AV.applicationId,\n };\n return request({\n path: '/bigquery/jobs',\n method: 'POST',\n data: AV._encode(data, null, true),\n authOptions: options,\n signKey: false,\n }).then(resp => AV._decode(resp).id);\n },\n\n /**\n * 监听 Insight 任务事件(未来推出独立部署的离线分析服务后开放)\n * \n * 仅在云引擎运行环境下有效。\n *
\n * @param {String} event 监听的事件,目前尚不支持。\n * @param {Function} 监听回调函数,接收 (err, id) 两个参数,err 表示错误信息,\n * id 表示任务 id。接下来你可以拿这个 id 使用AV.Insight.JobQuery 查询任务状态和结果。\n *\n */\n on: function(event, cb) {},\n }\n );\n\n /**\n * 创建一个对象,用于查询 Insight 任务状态和结果。\n * @class\n * @param {String} id 任务 id\n * @since 0.5.5\n */\n AV.Insight.JobQuery = function(id, className) {\n if (!id) {\n throw new Error('Please provide the job id.');\n }\n this.id = id;\n this.className = className;\n this._skip = 0;\n this._limit = 100;\n };\n\n _.extend(\n AV.Insight.JobQuery.prototype,\n /** @lends AV.Insight.JobQuery.prototype */ {\n /**\n * Sets the number of results to skip before returning any results.\n * This is useful for pagination.\n * Default is to skip zero results.\n * @param {Number} n the number of results to skip.\n * @return {AV.Query} Returns the query, so you can chain this call.\n */\n skip: function(n) {\n this._skip = n;\n return this;\n },\n\n /**\n * Sets the limit of the number of results to return. The default limit is\n * 100, with a maximum of 1000 results being returned at a time.\n * @param {Number} n the number of results to limit to.\n * @return {AV.Query} Returns the query, so you can chain this call.\n */\n limit: function(n) {\n this._limit = n;\n return this;\n },\n\n /**\n * 查询任务状态和结果,任务结果为一个 JSON 对象,包括 status 表示任务状态, totalCount 表示总数,\n * results 数组表示任务结果数组,previewCount 表示可以返回的结果总数,任务的开始和截止时间\n * startTime、endTime 等信息。\n *\n * @param {AuthOptions} [options]\n * @return {Promise} A promise that will be resolved with the result\n * of the function.\n *\n */\n find: function(options) {\n var params = {\n skip: this._skip,\n limit: this._limit,\n };\n\n return request({\n path: `/bigquery/jobs/${this.id}`,\n method: 'GET',\n query: params,\n authOptions: options,\n signKey: false,\n }).then(function(response) {\n if (response.error) {\n return Promise.reject(new AVError(response.code, response.error));\n }\n return Promise.resolve(response);\n });\n },\n }\n );\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/insight.js","const _ = require('underscore');\nconst { request: LCRequest } = require('./request');\nconst { getSessionToken } = require('./utils');\n\nmodule.exports = function(AV) {\n const getUserWithSessionToken = authOptions => {\n if (authOptions.user) {\n if (!authOptions.user._sessionToken) {\n throw new Error('authOptions.user is not signed in.');\n }\n return Promise.resolve(authOptions.user);\n }\n if (authOptions.sessionToken) {\n return AV.User._fetchUserBySessionToken(authOptions.sessionToken);\n }\n return AV.User.currentAsync();\n };\n\n const getSessionTokenAsync = authOptions => {\n const sessionToken = getSessionToken(authOptions);\n if (sessionToken) {\n return Promise.resolve(sessionToken);\n }\n return AV.User.currentAsync().then(user => {\n if (user) {\n return user.getSessionToken();\n }\n });\n };\n\n /**\n * Contains functions to deal with Friendship in LeanCloud.\n * @class\n */\n AV.Friendship = {\n /**\n * Request friendship.\n * @since 4.8.0\n * @param {String | AV.User | Object} options if an AV.User or string is given, it will be used as the friend.\n * @param {AV.User | string} options.friend The friend (or friend's objectId) to follow.\n * @param {Object} [options.attributes] key-value attributes dictionary to be used as conditions of followeeQuery.\n * @param {AuthOptions} [authOptions]\n * @return {PromiseAn AV.Conversation is a local representation of a LeanCloud realtime's\n * conversation. This class is a subclass of AV.Object, and retains the\n * same functionality of an AV.Object, but also extends it with various\n * conversation specific methods, like get members, creators of this conversation.\n *
\n *\n * @class AV.Conversation\n * @param {String} name The name of the Role to create.\n * @param {Object} [options]\n * @param {Boolean} [options.isSystem] Set this conversation as system conversation.\n * @param {Boolean} [options.isTransient] Set this conversation as transient conversation.\n */\nmodule.exports = AV.Object.extend(\n '_Conversation',\n /** @lends AV.Conversation.prototype */ {\n constructor(name, options = {}) {\n AV.Object.prototype.constructor.call(this, null, null);\n this.set('name', name);\n if (options.isSystem !== undefined) {\n this.set('sys', options.isSystem ? true : false);\n }\n if (options.isTransient !== undefined) {\n this.set('tr', options.isTransient ? true : false);\n }\n },\n /**\n * Get current conversation's creator.\n *\n * @return {String}\n */\n getCreator() {\n return this.get('c');\n },\n\n /**\n * Get the last message's time.\n *\n * @return {Date}\n */\n getLastMessageAt() {\n return this.get('lm');\n },\n\n /**\n * Get this conversation's members\n *\n * @return {String[]}\n */\n getMembers() {\n return this.get('m');\n },\n\n /**\n * Add a member to this conversation\n *\n * @param {String} member\n */\n addMember(member) {\n return this.add('m', member);\n },\n\n /**\n * Get this conversation's members who set this conversation as muted.\n *\n * @return {String[]}\n */\n getMutedMembers() {\n return this.get('mu');\n },\n\n /**\n * Get this conversation's name field.\n *\n * @return String\n */\n getName() {\n return this.get('name');\n },\n\n /**\n * Returns true if this conversation is transient conversation.\n *\n * @return {Boolean}\n */\n isTransient() {\n return this.get('tr');\n },\n\n /**\n * Returns true if this conversation is system conversation.\n *\n * @return {Boolean}\n */\n isSystem() {\n return this.get('sys');\n },\n\n /**\n * Send realtime message to this conversation, using HTTP request.\n *\n * @param {String} fromClient Sender's client id.\n * @param {String|Object} message The message which will send to conversation.\n * It could be a raw string, or an object with a `toJSON` method, like a\n * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息}\n * @param {Object} [options]\n * @param {Boolean} [options.transient] Whether send this message as transient message or not.\n * @param {String[]} [options.toClients] Ids of clients to send to. This option can be used only in system conversation.\n * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容}\n * @param {AuthOptions} [authOptions]\n * @return {Promise}\n */\n send(fromClient, message, options = {}, authOptions = {}) {\n const data = {\n from_peer: fromClient,\n conv_id: this.id,\n transient: false,\n message: serializeMessage(message),\n };\n if (options.toClients !== undefined) {\n data.to_peers = options.toClients;\n }\n if (options.transient !== undefined) {\n data.transient = options.transient ? true : false;\n }\n if (options.pushData !== undefined) {\n data.push_data = options.pushData;\n }\n return _request('rtm', 'messages', null, 'POST', data, authOptions);\n },\n\n /**\n * Send realtime broadcast message to all clients, via this conversation, using HTTP request.\n *\n * @param {String} fromClient Sender's client id.\n * @param {String|Object} message The message which will send to conversation.\n * It could be a raw string, or an object with a `toJSON` method, like a\n * realtime SDK's Message object. See more: {@link https://leancloud.cn/docs/realtime_guide-js.html#消息}.\n * @param {Object} [options]\n * @param {Object} [options.pushData] Push data to this message. See more: {@link https://url.leanapp.cn/pushData 推送消息内容}.\n * @param {Object} [options.validTill] The message will valid till this time.\n * @param {AuthOptions} [authOptions]\n * @return {Promise}\n */\n broadcast(fromClient, message, options = {}, authOptions = {}) {\n const data = {\n from_peer: fromClient,\n conv_id: this.id,\n message: serializeMessage(message),\n };\n if (options.pushData !== undefined) {\n data.push = options.pushData;\n }\n if (options.validTill !== undefined) {\n let ts = options.validTill;\n if (_.isDate(ts)) {\n ts = ts.getTime();\n }\n options.valid_till = ts;\n }\n return _request('rtm', 'broadcast', null, 'POST', data, authOptions);\n },\n }\n);\n\n\n\n// WEBPACK FOOTER //\n// ./src/conversation.js","const _ = require('underscore');\nconst { request } = require('./request');\nconst { ensureArray, parseDate } = require('./utils');\nconst AV = require('./av');\n\n/**\n * The version change interval for Leaderboard\n * @enum\n */\nAV.LeaderboardVersionChangeInterval = {\n NEVER: 'never',\n DAY: 'day',\n WEEK: 'week',\n MONTH: 'month',\n};\n\n/**\n * The order of the leaderboard results\n * @enum\n */\nAV.LeaderboardOrder = {\n ASCENDING: 'ascending',\n DESCENDING: 'descending',\n};\n\n/**\n * The update strategy for Leaderboard\n * @enum\n */\nAV.LeaderboardUpdateStrategy = {\n /** Only keep the best statistic. If the leaderboard is in descending order, the best statistic is the highest one. */\n BETTER: 'better',\n /** Keep the last updated statistic */\n LAST: 'last',\n /** Keep the sum of all updated statistics */\n SUM: 'sum',\n};\n\n/**\n * @typedef {Object} Ranking\n * @property {number} rank Starts at 0\n * @property {number} value the statistic value of this ranking\n * @property {AV.User} user The user of this ranking\n * @property {Statistic[]} [includedStatistics] Other statistics of the user, specified by the `includeStatistic` option of `AV.Leaderboard.getResults()`\n */\n\n/**\n * @typedef {Object} LeaderboardArchive\n * @property {string} statisticName\n * @property {number} version version of the leaderboard\n * @property {string} status\n * @property {string} url URL for the downloadable archive\n * @property {Date} activatedAt time when this version became active\n * @property {Date} deactivatedAt time when this version was deactivated by a version incrementing\n */\n\n/**\n * @class\n */\nfunction Statistic({ name, value, version }) {\n /**\n * @type {string}\n */\n this.name = name;\n /**\n * @type {number}\n */\n this.value = value;\n /**\n * @type {number?}\n */\n this.version = version;\n}\n\nconst parseStatisticData = statisticData => {\n const { statisticName: name, statisticValue: value, version } = AV._decode(\n statisticData\n );\n return new Statistic({ name, value, version });\n};\n\n/**\n * @class\n */\nAV.Leaderboard = function Leaderboard(statisticName) {\n /**\n * @type {string}\n */\n this.statisticName = statisticName;\n /**\n * @type {AV.LeaderboardOrder}\n */\n this.order = undefined;\n /**\n * @type {AV.LeaderboardUpdateStrategy}\n */\n this.updateStrategy = undefined;\n /**\n * @type {AV.LeaderboardVersionChangeInterval}\n */\n this.versionChangeInterval = undefined;\n /**\n * @type {number}\n */\n this.version = undefined;\n /**\n * @type {Date?}\n */\n this.nextResetAt = undefined;\n /**\n * @type {Date?}\n */\n this.createdAt = undefined;\n};\nconst Leaderboard = AV.Leaderboard;\n\n/**\n * Create an instance of Leaderboard for the give statistic name.\n * @param {string} statisticName\n * @return {AV.Leaderboard}\n */\nAV.Leaderboard.createWithoutData = statisticName =>\n new Leaderboard(statisticName);\n/**\n * (masterKey required) Create a new Leaderboard.\n * @param {Object} options\n * @param {string} options.statisticName\n * @param {AV.LeaderboardOrder} options.order\n * @param {AV.LeaderboardVersionChangeInterval} [options.versionChangeInterval] default to WEEK\n * @param {AV.LeaderboardUpdateStrategy} [options.updateStrategy] default to BETTER\n * @param {AuthOptions} [authOptions]\n * @return {Promise