rettiwt-api 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.js +54 -0
  3. package/.github/workflows/documentation.yml +29 -9
  4. package/.github/workflows/publish.yml +8 -3
  5. package/.prettierignore +3 -0
  6. package/.prettierrc +13 -0
  7. package/README.md +59 -61
  8. package/dist/Rettiwt.d.ts +19 -0
  9. package/dist/Rettiwt.js +30 -0
  10. package/dist/Rettiwt.js.map +1 -0
  11. package/dist/enums/ApiErrors.d.ts +30 -0
  12. package/dist/enums/ApiErrors.js +35 -0
  13. package/dist/enums/ApiErrors.js.map +1 -0
  14. package/dist/enums/HTTP.d.ts +11 -11
  15. package/dist/enums/HTTP.js +15 -16
  16. package/dist/enums/HTTP.js.map +1 -1
  17. package/dist/helper/JsonUtils.d.ts +26 -0
  18. package/dist/helper/JsonUtils.js +88 -0
  19. package/dist/helper/JsonUtils.js.map +1 -0
  20. package/dist/index.d.ts +10 -43
  21. package/dist/index.js +16 -55
  22. package/dist/index.js.map +1 -1
  23. package/dist/models/CursoredData.d.ts +37 -0
  24. package/dist/models/CursoredData.js +59 -0
  25. package/dist/models/CursoredData.js.map +1 -0
  26. package/dist/models/{data/Tweet.d.ts → Tweet.d.ts} +4 -4
  27. package/dist/models/{data/Tweet.js → Tweet.js} +7 -32
  28. package/dist/models/Tweet.js.map +1 -0
  29. package/dist/models/{data/User.d.ts → User.d.ts} +3 -3
  30. package/dist/models/{data/User.js → User.js} +3 -3
  31. package/dist/models/User.js.map +1 -0
  32. package/dist/services/FetcherService.d.ts +66 -0
  33. package/dist/services/FetcherService.js +207 -0
  34. package/dist/services/FetcherService.js.map +1 -0
  35. package/dist/services/TweetService.d.ts +88 -0
  36. package/dist/services/TweetService.js +244 -0
  37. package/dist/services/TweetService.js.map +1 -0
  38. package/dist/services/UserService.d.ts +60 -0
  39. package/dist/services/UserService.js +188 -0
  40. package/dist/services/UserService.js.map +1 -0
  41. package/dist/types/{Service.d.ts → CursoredData.d.ts} +3 -3
  42. package/dist/types/CursoredData.js +3 -0
  43. package/dist/types/CursoredData.js.map +1 -0
  44. package/dist/types/Tweet.js +1 -1
  45. package/dist/types/User.js +1 -1
  46. package/package.json +15 -19
  47. package/src/Rettiwt.ts +33 -0
  48. package/src/enums/ApiErrors.ts +30 -0
  49. package/src/enums/HTTP.ts +12 -12
  50. package/src/helper/JsonUtils.ts +86 -0
  51. package/src/index.ts +14 -57
  52. package/src/models/CursoredData.ts +64 -0
  53. package/src/models/Tweet.ts +116 -0
  54. package/src/models/User.ts +72 -0
  55. package/src/services/FetcherService.ts +183 -0
  56. package/src/services/TweetService.ts +153 -0
  57. package/src/services/UserService.ts +117 -0
  58. package/src/types/CursoredData.ts +24 -0
  59. package/src/types/Tweet.ts +35 -35
  60. package/src/types/User.ts +30 -30
  61. package/tsconfig.json +9 -9
  62. package/dist/config/env.d.ts +0 -5
  63. package/dist/config/env.js +0 -9
  64. package/dist/config/env.js.map +0 -1
  65. package/dist/enums/Errors.d.ts +0 -21
  66. package/dist/enums/Errors.js +0 -29
  67. package/dist/enums/Errors.js.map +0 -1
  68. package/dist/graphql/enums/Errors.d.ts +0 -21
  69. package/dist/graphql/enums/Errors.js +0 -29
  70. package/dist/graphql/enums/Errors.js.map +0 -1
  71. package/dist/graphql/queries/RootQuery.d.ts +0 -4
  72. package/dist/graphql/queries/RootQuery.js +0 -83
  73. package/dist/graphql/queries/RootQuery.js.map +0 -1
  74. package/dist/graphql/resolvers/AccountResolver.d.ts +0 -12
  75. package/dist/graphql/resolvers/AccountResolver.js +0 -84
  76. package/dist/graphql/resolvers/AccountResolver.js.map +0 -1
  77. package/dist/graphql/resolvers/ResolverBase.d.ts +0 -16
  78. package/dist/graphql/resolvers/ResolverBase.js +0 -23
  79. package/dist/graphql/resolvers/ResolverBase.js.map +0 -1
  80. package/dist/graphql/resolvers/TweetResolver.d.ts +0 -46
  81. package/dist/graphql/resolvers/TweetResolver.js +0 -302
  82. package/dist/graphql/resolvers/TweetResolver.js.map +0 -1
  83. package/dist/graphql/resolvers/UserResolver.d.ts +0 -48
  84. package/dist/graphql/resolvers/UserResolver.js +0 -334
  85. package/dist/graphql/resolvers/UserResolver.js.map +0 -1
  86. package/dist/graphql/types/Global.d.ts +0 -4
  87. package/dist/graphql/types/Global.js +0 -13
  88. package/dist/graphql/types/Global.js.map +0 -1
  89. package/dist/graphql/types/TweetTypes.d.ts +0 -4
  90. package/dist/graphql/types/TweetTypes.js +0 -160
  91. package/dist/graphql/types/TweetTypes.js.map +0 -1
  92. package/dist/graphql/types/UserTypes.d.ts +0 -3
  93. package/dist/graphql/types/UserTypes.js +0 -137
  94. package/dist/graphql/types/UserTypes.js.map +0 -1
  95. package/dist/models/args/TweetListArgs.d.ts +0 -21
  96. package/dist/models/args/TweetListArgs.js +0 -54
  97. package/dist/models/args/TweetListArgs.js.map +0 -1
  98. package/dist/models/args/UserListArgs.d.ts +0 -21
  99. package/dist/models/args/UserListArgs.js +0 -54
  100. package/dist/models/args/UserListArgs.js.map +0 -1
  101. package/dist/models/auth/AuthCookie.d.ts +0 -21
  102. package/dist/models/auth/AuthCookie.js +0 -33
  103. package/dist/models/auth/AuthCookie.js.map +0 -1
  104. package/dist/models/data/CursoredData.d.ts +0 -34
  105. package/dist/models/data/CursoredData.js +0 -42
  106. package/dist/models/data/CursoredData.js.map +0 -1
  107. package/dist/models/data/Tweet.js.map +0 -1
  108. package/dist/models/data/User.js.map +0 -1
  109. package/dist/server.d.ts +0 -1
  110. package/dist/server.js +0 -76
  111. package/dist/server.js.map +0 -1
  112. package/dist/services/auth/AccountService.d.ts +0 -83
  113. package/dist/services/auth/AccountService.js +0 -412
  114. package/dist/services/auth/AccountService.js.map +0 -1
  115. package/dist/services/auth/AuthService.d.ts +0 -31
  116. package/dist/services/auth/AuthService.js +0 -118
  117. package/dist/services/auth/AuthService.js.map +0 -1
  118. package/dist/services/data/TweetService.d.ts +0 -60
  119. package/dist/services/data/TweetService.js +0 -250
  120. package/dist/services/data/TweetService.js.map +0 -1
  121. package/dist/services/data/UserService.d.ts +0 -71
  122. package/dist/services/data/UserService.js +0 -278
  123. package/dist/services/data/UserService.js.map +0 -1
  124. package/dist/services/helper/Headers.d.ts +0 -19
  125. package/dist/services/helper/Headers.js +0 -62
  126. package/dist/services/helper/Headers.js.map +0 -1
  127. package/dist/services/helper/Parser.d.ts +0 -22
  128. package/dist/services/helper/Parser.js +0 -84
  129. package/dist/services/helper/Parser.js.map +0 -1
  130. package/dist/services/helper/extractors/Tweets.d.ts +0 -23
  131. package/dist/services/helper/extractors/Tweets.js +0 -200
  132. package/dist/services/helper/extractors/Tweets.js.map +0 -1
  133. package/dist/services/helper/extractors/Users.d.ts +0 -17
  134. package/dist/services/helper/extractors/Users.js +0 -151
  135. package/dist/services/helper/extractors/Users.js.map +0 -1
  136. package/dist/services/helper/payloads/LoginFlows.d.ts +0 -77
  137. package/dist/services/helper/payloads/LoginFlows.js +0 -92
  138. package/dist/services/helper/payloads/LoginFlows.js.map +0 -1
  139. package/dist/services/helper/urls/Authentication.d.ts +0 -4
  140. package/dist/services/helper/urls/Authentication.js +0 -11
  141. package/dist/services/helper/urls/Authentication.js.map +0 -1
  142. package/dist/services/util/CacheService.d.ts +0 -33
  143. package/dist/services/util/CacheService.js +0 -96
  144. package/dist/services/util/CacheService.js.map +0 -1
  145. package/dist/services/util/FetcherService.d.ts +0 -65
  146. package/dist/services/util/FetcherService.js +0 -202
  147. package/dist/services/util/FetcherService.js.map +0 -1
  148. package/dist/types/Args.d.ts +0 -11
  149. package/dist/types/Args.js +0 -4
  150. package/dist/types/Args.js.map +0 -1
  151. package/dist/types/Authentication.d.ts +0 -55
  152. package/dist/types/Authentication.js +0 -6
  153. package/dist/types/Authentication.js.map +0 -1
  154. package/dist/types/Resolvers.d.ts +0 -15
  155. package/dist/types/Resolvers.js +0 -3
  156. package/dist/types/Resolvers.js.map +0 -1
  157. package/dist/types/Rettiwt.d.ts +0 -16
  158. package/dist/types/Rettiwt.js +0 -3
  159. package/dist/types/Rettiwt.js.map +0 -1
  160. package/dist/types/Service.js +0 -5
  161. package/dist/types/Service.js.map +0 -1
  162. package/docs/.nojekyll +0 -1
  163. package/docs/assets/highlight.css +0 -64
  164. package/docs/assets/main.js +0 -58
  165. package/docs/assets/search.js +0 -1
  166. package/docs/assets/style.css +0 -1280
  167. package/docs/classes/AccountService.html +0 -286
  168. package/docs/classes/AuthCookie.html +0 -146
  169. package/docs/classes/AuthService.html +0 -147
  170. package/docs/classes/CacheService.html +0 -157
  171. package/docs/classes/Cursor.html +0 -102
  172. package/docs/classes/CursoredData.html +0 -126
  173. package/docs/classes/DataValidationError.html +0 -120
  174. package/docs/classes/FetcherService.html +0 -225
  175. package/docs/classes/Tweet.html +0 -210
  176. package/docs/classes/TweetEntities.html +0 -128
  177. package/docs/classes/TweetFilter.html +0 -233
  178. package/docs/classes/TweetListArgs.html +0 -118
  179. package/docs/classes/TweetService.html +0 -319
  180. package/docs/classes/User.html +0 -230
  181. package/docs/classes/UserListArgs.html +0 -118
  182. package/docs/classes/UserService.html +0 -355
  183. package/docs/enums/HttpMethods.html +0 -74
  184. package/docs/functions/Rettiwt.html +0 -100
  185. package/docs/index.html +0 -159
  186. package/docs/interfaces/IAuthCookie.html +0 -104
  187. package/docs/interfaces/ICursor.html +0 -77
  188. package/docs/interfaces/ICursoredData.html +0 -93
  189. package/docs/interfaces/IDataContext.html +0 -91
  190. package/docs/interfaces/IDataValidationError.html +0 -109
  191. package/docs/interfaces/IListArgs.html +0 -87
  192. package/docs/interfaces/ITweet.html +0 -176
  193. package/docs/interfaces/ITweetEntities.html +0 -104
  194. package/docs/interfaces/ITweetFilter.html +0 -158
  195. package/docs/interfaces/IUser.html +0 -194
  196. package/docs/modules.html +0 -111
  197. package/environment.d.ts +0 -11
  198. package/src/config/env.ts +0 -5
  199. package/src/enums/Errors.ts +0 -22
  200. package/src/graphql/enums/Errors.ts +0 -22
  201. package/src/graphql/queries/RootQuery.ts +0 -81
  202. package/src/graphql/resolvers/AccountResolver.ts +0 -22
  203. package/src/graphql/resolvers/ResolverBase.ts +0 -26
  204. package/src/graphql/resolvers/TweetResolver.ts +0 -225
  205. package/src/graphql/resolvers/UserResolver.ts +0 -257
  206. package/src/graphql/types/Global.ts +0 -10
  207. package/src/graphql/types/TweetTypes.ts +0 -158
  208. package/src/graphql/types/UserTypes.ts +0 -134
  209. package/src/models/args/TweetListArgs.ts +0 -47
  210. package/src/models/args/UserListArgs.ts +0 -47
  211. package/src/models/auth/AuthCookie.ts +0 -43
  212. package/src/models/data/CursoredData.ts +0 -45
  213. package/src/models/data/Tweet.ts +0 -118
  214. package/src/models/data/User.ts +0 -72
  215. package/src/server.ts +0 -37
  216. package/src/services/auth/AccountService.ts +0 -283
  217. package/src/services/auth/AuthService.ts +0 -81
  218. package/src/services/data/TweetService.ts +0 -197
  219. package/src/services/data/UserService.ts +0 -221
  220. package/src/services/helper/Headers.ts +0 -60
  221. package/src/services/helper/Parser.ts +0 -89
  222. package/src/services/helper/extractors/Tweets.ts +0 -190
  223. package/src/services/helper/extractors/Users.ts +0 -141
  224. package/src/services/helper/payloads/LoginFlows.ts +0 -90
  225. package/src/services/helper/urls/Authentication.ts +0 -6
  226. package/src/services/util/CacheService.ts +0 -76
  227. package/src/services/util/FetcherService.ts +0 -143
  228. package/src/types/Args.ts +0 -12
  229. package/src/types/Authentication.ts +0 -63
  230. package/src/types/Resolvers.ts +0 -18
  231. package/src/types/Rettiwt.ts +0 -20
  232. package/src/types/Service.ts +0 -24
package/.eslintignore ADDED
@@ -0,0 +1,3 @@
1
+ node_modules/
2
+ dist/
3
+ docs/
package/.eslintrc.js ADDED
@@ -0,0 +1,54 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ parserOptions: {
4
+ project: 'tsconfig.json',
5
+ tsconfigRootDir: __dirname,
6
+ sourceType: 'module',
7
+ },
8
+ plugins: ['@typescript-eslint/eslint-plugin', 'eslint-plugin-tsdoc'],
9
+ extends: ['plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended-requiring-type-checking'],
10
+ root: true,
11
+ env: {
12
+ node: true,
13
+ jest: true,
14
+ },
15
+ ignorePatterns: ['.eslintrc.js'],
16
+ rules: {
17
+ '@typescript-eslint/naming-convention': [
18
+ 'warn',
19
+ {
20
+ selector: ['class'],
21
+ format: ['PascalCase'],
22
+ },
23
+ {
24
+ selector: 'interface',
25
+ format: ['PascalCase'],
26
+ prefix: ['I'],
27
+ },
28
+ {
29
+ selector: 'enum',
30
+ format: ['PascalCase'],
31
+ prefix: ['E'],
32
+ },
33
+ {
34
+ selector: ['variableLike', 'memberLike'],
35
+ format: ['camelCase'],
36
+ },
37
+ {
38
+ selector: 'enumMember',
39
+ format: ['UPPER_CASE'],
40
+ },
41
+ ],
42
+ '@typescript-eslint/explicit-function-return-type': 'error',
43
+ '@typescript-eslint/explicit-module-boundary-types': 'error',
44
+ '@typescript-eslint/no-explicit-any': 'warn',
45
+ '@typescript-eslint/no-extraneous-class': [
46
+ 'warn',
47
+ {
48
+ allowEmpty: true,
49
+ },
50
+ ],
51
+ '@typescript-eslint/no-inferrable-types': 'off',
52
+ 'tsdoc/syntax': 'warn',
53
+ },
54
+ };
@@ -1,27 +1,47 @@
1
1
  name: Documentation
2
2
  run-name: Building the documentation for the release
3
+
3
4
  on:
4
5
  push:
5
6
  branches: release
6
7
 
7
8
  jobs:
8
- documentation:
9
+ # Builds and packages the documentation
10
+ build:
9
11
  runs-on: ubuntu-latest
10
- permissions:
11
- contents: write
12
12
  steps:
13
+ # Setting up Node
13
14
  - uses: actions/checkout@v3
14
15
  - uses: actions/setup-node@v3
15
16
  with:
16
17
  node-version: '18.x'
18
+
17
19
  # Installing dependencies
18
20
  - run: yarn
19
-
20
- # Generating documentations
21
21
  - run: npx typedoc src/index.ts
22
22
 
23
- # Commiting the documentations
24
- - uses: stefanzweifel/git-auto-commit-action@v4
23
+ # Packaging the static site as artifact
24
+ - uses: actions/upload-pages-artifact@v2
25
25
  with:
26
- commit_message: Updated documentations
27
- branch: release
26
+ path: ./docs
27
+
28
+ # Deploys the packaged documentation
29
+ deploy:
30
+ # Building and packaging the documentation
31
+ needs: build
32
+
33
+ # Granting necessary permissions
34
+ permissions:
35
+ pages: write
36
+ id-token: write
37
+
38
+ # Setting up GH pages environment
39
+ environment:
40
+ name: github-pages
41
+ url: ${{ steps.deployment.outputs.page_url }}
42
+
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ # Deploying to gh pages
46
+ - id: deployment
47
+ uses: actions/deploy-pages@v2
@@ -1,6 +1,3 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
-
4
1
  name: Publish
5
2
  run-name: Publishing the package to NPM
6
3
 
@@ -9,16 +6,24 @@ on:
9
6
  types: [created]
10
7
 
11
8
  jobs:
9
+ # Packages and publishes the package to NPM
12
10
  publish-npm:
13
11
  runs-on: ubuntu-latest
14
12
  steps:
13
+ # Setting up Node
15
14
  - uses: actions/checkout@v3
16
15
  - uses: actions/setup-node@v3
17
16
  with:
18
17
  node-version: '18.x'
19
18
  registry-url: https://registry.npmjs.org/
19
+
20
+ # Installing dependencies
20
21
  - run: yarn
22
+
23
+ # Building the package
21
24
  - run: yarn run build
25
+
26
+ # Publishing to NPM
22
27
  - run: npm publish
23
28
  env:
24
29
  NODE_AUTH_TOKEN: ${{secrets.npm_token}}
@@ -0,0 +1,3 @@
1
+ node_modules/
2
+ dist/
3
+ docs/
package/.prettierrc ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "arrowParens": "always",
3
+ "bracketSpacing": true,
4
+ "endOfLine": "auto",
5
+ "printWidth": 120,
6
+ "quoteProps": "consistent",
7
+ "semi": true,
8
+ "singleQuote": true,
9
+ "tabWidth": 4,
10
+ "trailingComma": "all",
11
+ "useTabs": true,
12
+ "vueIndentScriptAndStyle": true
13
+ }
package/README.md CHANGED
@@ -1,84 +1,82 @@
1
1
  # Rettiwt-API
2
2
 
3
- An API for fetching data from TwitterAPI, without any rate limits!
3
+ An API for fetching data from Twitter for free!
4
4
 
5
- #### **This API is not a replacement of official Twitter API, since it does not scale**
5
+ ## Prerequisites
6
6
 
7
- #### **It works well for small applications like the one side project you started and are never gonna finish**
7
+ - NodeJS 18.14.2
8
+ - A working Twitter account
8
9
 
9
- #### **If you want something that will scale as you application grows, Twitter API is the way to go**
10
+ ## Installation
10
11
 
11
- #### **The API can either be used as a GraphQL Server or as a standalone npm library**
12
+ 1. Initialize a new Node.JS project using the command `npm init`.
13
+ 2. Install the package either via npm or yarn:
14
+ - For npm, use the command `npm install --save rettiwt-api`
15
+ - For yarn, use the command `yarn add rettiwt-api`
12
16
 
13
- #### **For complete documentation and API reference, head over to the [documentation](https://rishikant181.github.io/Rettiwt-API/)**
17
+ Although the above process initializes a new project, that is, in fact, not necessary and you may add it to an existing Node.JS project and omit the first step altogether.
14
18
 
15
- ## 1. GraphQL Server
19
+ ## Getting started
16
20
 
17
- Using the API as a GraphQL enables complex nested queries to fetch data from twitter.
18
- To use the API as a server,
21
+ 1. Generate credentials using [rettiwt-auth](https://www.npmjs.com/package/rettiwt-auth) package, by following these [steps](https://rishikant181.github.io/Rettiwt-Auth/#md:cli-usage).
22
+ 2. Copy the value of the 'cookies' field from the generated credentials and store it somewhere safe. Let's call this our API_KEY.
23
+ 3. Create a new instance of Rettiwt, passing in the API key:
24
+ `const rettiwt = Rettiwt(API_KEY);`
25
+ 4. Use the created [Rettiwt](https://rishikant181.github.io/Rettiwt-API/classes/Rettiwt.html) instance to fetch data from Twitter.
19
26
 
20
- 1. Clone the repo's release branch
21
- 2. Build the project using 'npm run build'
22
- 3. Set the environment variables:
23
- - APP_PORT -> The port number where the server will listen to
24
- - DEVELOPMENT -> Whether to run the server in development mode or not
25
- 4. Start the server using 'npm run start'
26
- 5. Make graphql requests to server listening on localhost:port/graphql
27
+ **Note:** The API_KEY (cookie) that we generated, is a very sensitive information and provides all access to the Twitter account. Therefore, it is generally recommended to store it as an environment variable and use it from there.
27
28
 
28
- **You can go to localhost:port/graphql to see the graphql schema**
29
+ ## Usage
29
30
 
30
- ## 2. NPM Package
31
+ The following examples may help you to get started using the library:
31
32
 
32
- The API can also be used as a standalone npm package.
33
- The limitation is that, large number of data cannot be fetched automatically, and the data needs to fetched in batches, by using cursors.
34
- Further nested queries are not possible.
35
- To use the API as an npm package,
36
-
37
- 1. In your node project, install the package using 'npm install --save rettiwt-api'.
38
- 2. import { Rettiwt } from 'rettiwt-api'.
39
- ```
40
- const rettiwt = Rettiwt({
41
- <put your authentication tokens here. For details, refer to section below>
42
- }).
43
- ```
44
- 3. Use the created [Rettiwt](https://rishikant181.github.io/Rettiwt-API/functions/Rettiwt.html) instance to fetch data from Twitter.
45
-
46
- **The authentication tokens can be generated in the following way:**
47
-
48
- #### A. GraphQL Server:
49
-
50
- 1. Make the following query to the GraphQL server:
33
+ ### 1. Getting the details of a target Twitter user
51
34
 
52
35
  ```
53
- query {
54
- Login(email: "your_twitter_email", userName: "your_twitter_username", password: "your_twitter_password") {
55
- auth_token
56
- ct0
57
- kdt
58
- twid
59
- }
60
- }
36
+ // Creating a new Rettiwt instance using the API_KEY
37
+ const rettiwt = Rettiwt(API_KEY);
38
+
39
+ // Fetching the details of the user whose username is <username>
40
+ rettiwt.user.details('<username>')
41
+ .then(details => {
42
+ ...
43
+ })
44
+ .catch(error => {
45
+ ...
46
+ });
61
47
  ```
62
48
 
63
- 1. This will give you 4 tokens: 'auth_token', 'ct0', 'kdt' and 'twid'.
64
- 2. Pass the four tokens in the headers while making any request made to the GraphQL server for fetching data.
65
-
66
- #### B. NPM Library:
67
-
68
- 1. Use the [Rettiwt().account.login](https://rishikant181.github.io/Rettiwt-API/classes/AccountService.html#login) method to get back 4 tokens: 'auth_token', 'ct0', 'kdt' and 'twid'.
69
- 2. Use these four tokens to initialize a new [Rettiwt](https://rishikant181.github.io/Rettiwt-API/functions/Rettiwt.html) instance as follows:
49
+ ### 2. Getting the list of tweets that match a given filter
70
50
 
71
51
  ```
72
- const rettiwt = new Rettiwt({
73
- auth_token: "received_auth_token",
74
- ct0: "received_ct0_token",
75
- kdt: "received_kdt_token",
76
- twid: "received_twid_token"
77
- });
52
+ // Creating a new Rettiwt instance using the API_KEY
53
+ const rettiwt = Rettiwt(API_KEY);
54
+
55
+ /**
56
+ * Fetching the list of tweets that:
57
+ * - are made by a user with username <username>,
58
+ * - contain the words <word1> and <word2>
59
+ */
60
+ rettiwt.tweet.search({
61
+ fromUsers: ['<username>'],
62
+ words: ['<word1>', '<word2>']
63
+ })
64
+ .then(data => {
65
+ ...
66
+ })
67
+ .catch(err => {
68
+ ...
69
+ })
78
70
  ```
79
71
 
80
- 3. Use the created [Rettiwt](https://rishikant181.github.io/Rettiwt-API/functions/Rettiwt.html) instance to fetch data.
72
+ For more information regarding the different available filter options, please refer to [TweetFilter](https://rishikant181.github.io/Rettiwt-API/classes/TweetFilter.html).
73
+
74
+ ## API Reference
75
+
76
+ The complete API reference can be found at [this](https://rishikant181.github.io/Rettiwt-API/) page.
81
77
 
82
- ### **Due to changes in Twitter API, all methods now require logging in and using the tokens for authentication**
78
+ ## Additional information
83
79
 
84
- ### **I'M NOT RESPONSIBLE IF YOU GET YOUR TWITTER ACCOUNT BANNED!**
80
+ - This API uses the cookies of a Twitter account to fetch data from Twitter and as such, there is always a chance (altough a measly one) of getting the account banned by Twitter algorithm.
81
+ - From personal experience, not a single one of my accounts has ever been banned by using this library, and this is coming from someone who has been using his primary Twitter account to fetch large amounts of data from Twitter for over 1.5 years now, since the conception of this project.
82
+ - There have been no reports of accounts getting banned, but you have been warned, even though the chances of getting banned is negligible, it is not zero!
@@ -0,0 +1,19 @@
1
+ import { TweetService } from './services/TweetService';
2
+ import { UserService } from './services/UserService';
3
+ /**
4
+ * The class for fetching data from Twitter.
5
+ *
6
+ * @public
7
+ */
8
+ export declare class Rettiwt {
9
+ /** The instance used to fetch data related to tweets. */
10
+ tweet: TweetService;
11
+ /** The instance used to fetch data related to users. */
12
+ user: UserService;
13
+ /**
14
+ * Initializes a new Rettiwt instance using the given api key.
15
+ *
16
+ * @param apiKey - The apiKey (cookie) to be used for authenticating Rettiwt against Twitter.
17
+ */
18
+ constructor(apiKey: string);
19
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Rettiwt = void 0;
4
+ // PACKAGE
5
+ var rettiwt_auth_1 = require("rettiwt-auth");
6
+ // SERVICES
7
+ var TweetService_1 = require("./services/TweetService");
8
+ var UserService_1 = require("./services/UserService");
9
+ /**
10
+ * The class for fetching data from Twitter.
11
+ *
12
+ * @public
13
+ */
14
+ var Rettiwt = /** @class */ (function () {
15
+ /**
16
+ * Initializes a new Rettiwt instance using the given api key.
17
+ *
18
+ * @param apiKey - The apiKey (cookie) to be used for authenticating Rettiwt against Twitter.
19
+ */
20
+ function Rettiwt(apiKey) {
21
+ // Preparing auth credentials
22
+ var cred = new rettiwt_auth_1.AuthCredential(apiKey.split(';'));
23
+ // Initalizing service instances
24
+ this.tweet = new TweetService_1.TweetService(cred);
25
+ this.user = new UserService_1.UserService(cred);
26
+ }
27
+ return Rettiwt;
28
+ }());
29
+ exports.Rettiwt = Rettiwt;
30
+ //# sourceMappingURL=Rettiwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Rettiwt.js","sourceRoot":"","sources":["../src/Rettiwt.ts"],"names":[],"mappings":";;;AAAA,UAAU;AACV,6CAA8C;AAE9C,WAAW;AACX,wDAAuD;AACvD,sDAAqD;AAErD;;;;GAIG;AACH;IAOC;;;;OAIG;IACH,iBAAY,MAAc;QACzB,6BAA6B;QAC7B,IAAM,IAAI,GAAmB,IAAI,6BAAc,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAEnE,gCAAgC;QAChC,IAAI,CAAC,KAAK,GAAG,IAAI,2BAAY,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,yBAAW,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IACF,cAAC;AAAD,CAAC,AApBD,IAoBC;AApBY,0BAAO"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The different types of api error messages.
3
+ *
4
+ * @public
5
+ */
6
+ export declare enum EApiErrors {
7
+ COULD_NOT_AUTHENTICATE = "Failed to authenticate",
8
+ RESOURCE_NOT_FOUND = "Requested resource not found",
9
+ MISSING_PARAMETER = "Missing named parameter",
10
+ USER_NOT_FOUND = "Requested user not found",
11
+ USER_SUSPENDED = "Requested user has been suspended",
12
+ ACCOUNT_SUSPENDED = "Account has been suspended",
13
+ RATE_LIMIT_EXCEEDED = "Rate limit exceeded",
14
+ INTERNAL_ERROR = "Internal server error",
15
+ TIME_ERROR = "Mismatched data/time with server",
16
+ ALREADY_FAVORITED = "Tweet already favorited",
17
+ STATUS_NOT_FOUND = "Requested tweeet not found",
18
+ NOT_AUTHORIZED = "Not authorized to view tweet",
19
+ DAILY_STATUS_LIMIT_EXCEEDED = "Exceeded daily tweet update limit",
20
+ TWEET_LENGTH_EXCEEDED = "Exceeded tweet text maximum length",
21
+ DUPLICATE_STATUS = "Tweet already posted",
22
+ BAD_AUTHENTICATION = "Invalid authentication data",
23
+ RESOURCE_NOT_ALLOWED = "Not authorized to access requested resource",
24
+ AUTOMATED_REQUEST_ERROR = "Automated request detected",
25
+ ACCOUNT_LOCKED = "Account has been locked",
26
+ ALREADY_RETWEETED = "Tweet already retweeted",
27
+ TWEET_NOT_FOUND = "Requested tweet not found",
28
+ TWEET_VIOLATED_RULES = "Requestd tweet has been removed for rules violation",
29
+ DISABLED_TWEET_ACTIONS = "Reqeusted action disabled on the tweet"
30
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EApiErrors = void 0;
4
+ /**
5
+ * The different types of api error messages.
6
+ *
7
+ * @public
8
+ */
9
+ var EApiErrors;
10
+ (function (EApiErrors) {
11
+ EApiErrors["COULD_NOT_AUTHENTICATE"] = "Failed to authenticate";
12
+ EApiErrors["RESOURCE_NOT_FOUND"] = "Requested resource not found";
13
+ EApiErrors["MISSING_PARAMETER"] = "Missing named parameter";
14
+ EApiErrors["USER_NOT_FOUND"] = "Requested user not found";
15
+ EApiErrors["USER_SUSPENDED"] = "Requested user has been suspended";
16
+ EApiErrors["ACCOUNT_SUSPENDED"] = "Account has been suspended";
17
+ EApiErrors["RATE_LIMIT_EXCEEDED"] = "Rate limit exceeded";
18
+ EApiErrors["INTERNAL_ERROR"] = "Internal server error";
19
+ EApiErrors["TIME_ERROR"] = "Mismatched data/time with server";
20
+ EApiErrors["ALREADY_FAVORITED"] = "Tweet already favorited";
21
+ EApiErrors["STATUS_NOT_FOUND"] = "Requested tweeet not found";
22
+ EApiErrors["NOT_AUTHORIZED"] = "Not authorized to view tweet";
23
+ EApiErrors["DAILY_STATUS_LIMIT_EXCEEDED"] = "Exceeded daily tweet update limit";
24
+ EApiErrors["TWEET_LENGTH_EXCEEDED"] = "Exceeded tweet text maximum length";
25
+ EApiErrors["DUPLICATE_STATUS"] = "Tweet already posted";
26
+ EApiErrors["BAD_AUTHENTICATION"] = "Invalid authentication data";
27
+ EApiErrors["RESOURCE_NOT_ALLOWED"] = "Not authorized to access requested resource";
28
+ EApiErrors["AUTOMATED_REQUEST_ERROR"] = "Automated request detected";
29
+ EApiErrors["ACCOUNT_LOCKED"] = "Account has been locked";
30
+ EApiErrors["ALREADY_RETWEETED"] = "Tweet already retweeted";
31
+ EApiErrors["TWEET_NOT_FOUND"] = "Requested tweet not found";
32
+ EApiErrors["TWEET_VIOLATED_RULES"] = "Requestd tweet has been removed for rules violation";
33
+ EApiErrors["DISABLED_TWEET_ACTIONS"] = "Reqeusted action disabled on the tweet";
34
+ })(EApiErrors || (exports.EApiErrors = EApiErrors = {}));
35
+ //# sourceMappingURL=ApiErrors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApiErrors.js","sourceRoot":"","sources":["../../src/enums/ApiErrors.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,IAAY,UAwBX;AAxBD,WAAY,UAAU;IACrB,+DAAiD,CAAA;IACjD,iEAAmD,CAAA;IACnD,2DAA6C,CAAA;IAC7C,yDAA2C,CAAA;IAC3C,kEAAoD,CAAA;IACpD,8DAAgD,CAAA;IAChD,yDAA2C,CAAA;IAC3C,sDAAwC,CAAA;IACxC,6DAA+C,CAAA;IAC/C,2DAA6C,CAAA;IAC7C,6DAA+C,CAAA;IAC/C,6DAA+C,CAAA;IAC/C,+EAAiE,CAAA;IACjE,0EAA4D,CAAA;IAC5D,uDAAyC,CAAA;IACzC,gEAAkD,CAAA;IAClD,kFAAoE,CAAA;IACpE,oEAAsD,CAAA;IACtD,wDAA0C,CAAA;IAC1C,2DAA6C,CAAA;IAC7C,2DAA6C,CAAA;IAC7C,0FAA4E,CAAA;IAC5E,+EAAiE,CAAA;AAClE,CAAC,EAxBW,UAAU,0BAAV,UAAU,QAwBrB"}
@@ -3,15 +3,15 @@
3
3
  *
4
4
  * @internal
5
5
  */
6
- export declare enum HttpStatus {
7
- BadRequest = 400,
8
- Unauthorized = 401,
9
- Forbidden = 403,
10
- NotFound = 404,
11
- MethodNotAllowed = 405,
12
- RequestTimeout = 408,
13
- TooManyRequests = 429,
14
- InternalServerError = 500,
15
- BadGateway = 502,
16
- ServiceUnavailable = 503
6
+ export declare enum EHttpStatus {
7
+ BAD_REQUEST = 400,
8
+ UNAUTHORIZED = 401,
9
+ FORBIDDEN = 403,
10
+ NOT_FOUND = 404,
11
+ METHOD_NOT_ALLOWED = 405,
12
+ REQUEST_TIMEOUT = 408,
13
+ TOO_MANY_REQUESTS = 429,
14
+ INTERNAL_SERVER_ERROR = 500,
15
+ BAD_GATEWAY = 502,
16
+ SERVICE_UNAVAILABLE = 503
17
17
  }
@@ -1,23 +1,22 @@
1
1
  "use strict";
2
- exports.__esModule = true;
3
- exports.HttpStatus = void 0;
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EHttpStatus = void 0;
4
4
  /**
5
5
  * The different types of http status codes
6
6
  *
7
7
  * @internal
8
8
  */
9
- var HttpStatus;
10
- (function (HttpStatus) {
11
- HttpStatus[HttpStatus["BadRequest"] = 400] = "BadRequest";
12
- HttpStatus[HttpStatus["Unauthorized"] = 401] = "Unauthorized";
13
- HttpStatus[HttpStatus["Forbidden"] = 403] = "Forbidden";
14
- HttpStatus[HttpStatus["NotFound"] = 404] = "NotFound";
15
- HttpStatus[HttpStatus["MethodNotAllowed"] = 405] = "MethodNotAllowed";
16
- HttpStatus[HttpStatus["RequestTimeout"] = 408] = "RequestTimeout";
17
- HttpStatus[HttpStatus["TooManyRequests"] = 429] = "TooManyRequests";
18
- HttpStatus[HttpStatus["InternalServerError"] = 500] = "InternalServerError";
19
- HttpStatus[HttpStatus["BadGateway"] = 502] = "BadGateway";
20
- HttpStatus[HttpStatus["ServiceUnavailable"] = 503] = "ServiceUnavailable";
21
- })(HttpStatus = exports.HttpStatus || (exports.HttpStatus = {}));
22
- ;
9
+ var EHttpStatus;
10
+ (function (EHttpStatus) {
11
+ EHttpStatus[EHttpStatus["BAD_REQUEST"] = 400] = "BAD_REQUEST";
12
+ EHttpStatus[EHttpStatus["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
13
+ EHttpStatus[EHttpStatus["FORBIDDEN"] = 403] = "FORBIDDEN";
14
+ EHttpStatus[EHttpStatus["NOT_FOUND"] = 404] = "NOT_FOUND";
15
+ EHttpStatus[EHttpStatus["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
16
+ EHttpStatus[EHttpStatus["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
17
+ EHttpStatus[EHttpStatus["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
18
+ EHttpStatus[EHttpStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
19
+ EHttpStatus[EHttpStatus["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
20
+ EHttpStatus[EHttpStatus["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
21
+ })(EHttpStatus || (exports.EHttpStatus = EHttpStatus = {}));
23
22
  //# sourceMappingURL=HTTP.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HTTP.js","sourceRoot":"","sources":["../../src/enums/HTTP.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,IAAY,UAWX;AAXD,WAAY,UAAU;IAClB,yDAAgB,CAAA;IAChB,6DAAkB,CAAA;IAClB,uDAAe,CAAA;IACf,qDAAc,CAAA;IACd,qEAAsB,CAAA;IACtB,iEAAoB,CAAA;IACpB,mEAAqB,CAAA;IACrB,2EAAyB,CAAA;IACzB,yDAAgB,CAAA;IAChB,yEAAwB,CAAA;AAC5B,CAAC,EAXW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAWrB;AAAA,CAAC"}
1
+ {"version":3,"file":"HTTP.js","sourceRoot":"","sources":["../../src/enums/HTTP.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,IAAY,WAWX;AAXD,WAAY,WAAW;IACtB,6DAAiB,CAAA;IACjB,+DAAkB,CAAA;IAClB,yDAAe,CAAA;IACf,yDAAe,CAAA;IACf,2EAAwB,CAAA;IACxB,qEAAqB,CAAA;IACrB,yEAAuB,CAAA;IACvB,iFAA2B,CAAA;IAC3B,6DAAiB,CAAA;IACjB,6EAAyB,CAAA;AAC1B,CAAC,EAXW,WAAW,2BAAX,WAAW,QAWtB"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Search for all the sub-objects (even deep-nested ones) that have the given key-value pair(filter).
3
+ *
4
+ * @param data - The data on which search is to be performed.
5
+ * @param key - The key of the key-value pair to search.
6
+ * @param value - The value of the key-value pait to search.
7
+ * @returns The list of sub-objects from the given object, having the given key-value pair.
8
+ *
9
+ * @internal
10
+ */
11
+ export declare function findByFilter<T>(data: NonNullable<unknown>, key: string, value: string): T[];
12
+ /**
13
+ * @param text - The text to be normalized.
14
+ * @returns The text after being formatted to remove unnecessary characters.
15
+ *
16
+ * @internal
17
+ */
18
+ export declare function normalizeText(text: string): string;
19
+ /**
20
+ * Searches for the key which has the given value in the given object.
21
+ *
22
+ * @param data - The data on which search is to be performed.
23
+ * @param value - The value to search.
24
+ * @returns The key with the given value.
25
+ */
26
+ export declare function findKeyByValue(data: NonNullable<unknown>, value: string): string | undefined;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findKeyByValue = exports.normalizeText = exports.findByFilter = void 0;
4
+ /**
5
+ * Search for all the sub-objects (even deep-nested ones) that have the given key-value pair(filter).
6
+ *
7
+ * @param data - The data on which search is to be performed.
8
+ * @param key - The key of the key-value pair to search.
9
+ * @param value - The value of the key-value pait to search.
10
+ * @returns The list of sub-objects from the given object, having the given key-value pair.
11
+ *
12
+ * @internal
13
+ */
14
+ function findByFilter(data, key, value) {
15
+ /**
16
+ * The list containing all the objects matching given filter.
17
+ */
18
+ var res = [];
19
+ /**
20
+ * If the data is an array, recursively run the function of each element of the array and merge the results.
21
+ */
22
+ if (Array.isArray(data)) {
23
+ /**
24
+ * findByFilter returns an array.
25
+ * map() also returns an array.
26
+ * Therefore, map(item =\> findByFilter(.......)) returns an array of arrays.
27
+ * Therefore, using ... operator to spread the 2-D array in 1-D array.
28
+ */
29
+ res = res.concat.apply(res, data.map(function (item) { return findByFilter(item, key, value); }));
30
+ }
31
+ // If the data is an object
32
+ else if (typeof data == 'object') {
33
+ /**
34
+ * If the object includes the key and the value specified by the key matches the filter, add it to the result.
35
+ */
36
+ if (Object.keys(data).includes(key) && data[key] == value) {
37
+ res.push(data);
38
+ }
39
+ /**
40
+ * Recursively run the function on each value specified by each key in the object, for subsequent matches.
41
+ */
42
+ for (var _i = 0, _a = Object.entries(data); _i < _a.length; _i++) {
43
+ var _b = _a[_i], v = _b[1];
44
+ res = res.concat(findByFilter(v, key, value));
45
+ }
46
+ }
47
+ return res;
48
+ }
49
+ exports.findByFilter = findByFilter;
50
+ /**
51
+ * @param text - The text to be normalized.
52
+ * @returns The text after being formatted to remove unnecessary characters.
53
+ *
54
+ * @internal
55
+ */
56
+ function normalizeText(text) {
57
+ var normalizedText = ''; // To store the normalized text
58
+ // Removing unnecessary full stops, and other characters
59
+ normalizedText = text.replace(/\n/g, '.').replace(/[.]+[\s+.\s+]+/g, '. ');
60
+ // Adding full-stop to the end if does not exist already
61
+ normalizedText = normalizedText.endsWith('.') ? normalizedText : normalizedText + '.';
62
+ return normalizedText;
63
+ }
64
+ exports.normalizeText = normalizeText;
65
+ /**
66
+ * Searches for the key which has the given value in the given object.
67
+ *
68
+ * @param data - The data on which search is to be performed.
69
+ * @param value - The value to search.
70
+ * @returns The key with the given value.
71
+ */
72
+ function findKeyByValue(data, value) {
73
+ // Finding the key-value pairs that have the given value
74
+ var kvPair = Object.entries(data).filter(function (_a) {
75
+ var v = _a[1];
76
+ return v == value;
77
+ })[0];
78
+ // If a match is found
79
+ if (kvPair) {
80
+ return kvPair[0];
81
+ }
82
+ // If no match is found
83
+ else {
84
+ return undefined;
85
+ }
86
+ }
87
+ exports.findKeyByValue = findKeyByValue;
88
+ //# sourceMappingURL=JsonUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonUtils.js","sourceRoot":"","sources":["../../src/helper/JsonUtils.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAAI,IAA0B,EAAE,GAAW,EAAE,KAAa;IACrF;;OAEG;IACH,IAAI,GAAG,GAAQ,EAAE,CAAC;IAElB;;OAEG;IACH,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACxB;;;;;WAKG;QACH,GAAG,GAAG,GAAG,CAAC,MAAM,OAAV,GAAG,EAAW,IAAI,CAAC,GAAG,CAAC,UAAC,IAAI,IAAK,OAAA,YAAY,CAAI,IAA4B,EAAE,GAAG,EAAE,KAAK,CAAC,EAAzD,CAAyD,CAAC,CAAC,CAAC;KACnG;IACD,2BAA2B;SACtB,IAAI,OAAO,IAAI,IAAI,QAAQ,EAAE;QACjC;;WAEG;QACH,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAwB,CAAC,IAAI,KAAK,EAAE;YAC/E,GAAG,CAAC,IAAI,CAAC,IAAS,CAAC,CAAC;SACpB;QAED;;WAEG;QACH,KAAoB,UAAoB,EAApB,KAAA,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAApB,cAAoB,EAApB,IAAoB,EAAE;YAA/B,IAAA,WAAK,EAAF,CAAC,QAAA;YACd,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAI,CAAyB,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;SACzE;KACD;IAED,OAAO,GAAG,CAAC;AACZ,CAAC;AApCD,oCAoCC;AAED;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,IAAY;IACzC,IAAI,cAAc,GAAW,EAAE,CAAC,CAAC,+BAA+B;IAEhE,wDAAwD;IACxD,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAE3E,wDAAwD;IACxD,cAAc,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,GAAG,GAAG,CAAC;IAEtF,OAAO,cAAc,CAAC;AACvB,CAAC;AAVD,sCAUC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc,CAAC,IAA0B,EAAE,KAAa;IACvE,wDAAwD;IACxD,IAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,UAAC,EAAK;YAAF,CAAC,QAAA;QAAM,OAAA,CAAC,IAAI,KAAK;IAAV,CAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAErE,sBAAsB;IACtB,IAAI,MAAM,EAAE;QACX,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;KACjB;IACD,uBAAuB;SAClB;QACJ,OAAO,SAAS,CAAC;KACjB;AACF,CAAC;AAZD,wCAYC"}