musora-content-services 2.121.2 → 2.122.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 (233) hide show
  1. package/.claude/settings.local.json +16 -0
  2. package/.coderabbit.yaml +0 -0
  3. package/.editorconfig +0 -0
  4. package/.github/pull_request_template.md +0 -0
  5. package/.github/workflows/conventional-commits.yaml +0 -0
  6. package/.github/workflows/docs.js.yml +0 -0
  7. package/.github/workflows/node.js.yml +0 -0
  8. package/.prettierignore +0 -0
  9. package/.prettierrc +0 -0
  10. package/.yarnrc.yml +1 -0
  11. package/CHANGELOG.md +19 -0
  12. package/CLAUDE.md +0 -0
  13. package/README.md +0 -0
  14. package/babel.config.cjs +0 -0
  15. package/check_content.js +30 -0
  16. package/check_content.mjs +32 -0
  17. package/jest.config.js +0 -0
  18. package/jsdoc.json +0 -0
  19. package/package.json +1 -1
  20. package/src/constants/award-assets.js +0 -0
  21. package/src/constants/membership-permissions.ts +0 -0
  22. package/src/contentMetaData.js +36 -0
  23. package/src/contentTypeConfig.js +32 -5
  24. package/src/filterBuilder.js +0 -0
  25. package/src/index.d.ts +0 -0
  26. package/src/index.js +0 -0
  27. package/src/infrastructure/http/HttpClient.ts +0 -0
  28. package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
  29. package/src/infrastructure/http/index.ts +0 -0
  30. package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
  31. package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
  32. package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
  33. package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
  34. package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
  35. package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
  36. package/src/lib/ads/monoid.ts +0 -0
  37. package/src/lib/ads/semigroup.ts +0 -0
  38. package/src/lib/brands.ts +0 -0
  39. package/src/lib/lastUpdated.js +0 -0
  40. package/src/lib/sanity/filter.ts +0 -0
  41. package/src/lib/sanity/query.ts +0 -0
  42. package/src/services/api/types.js +0 -0
  43. package/src/services/api/types.ts +0 -0
  44. package/src/services/awards/award-callbacks.js +0 -0
  45. package/src/services/awards/award-query.js +0 -0
  46. package/src/services/awards/internal/.indexignore +0 -0
  47. package/src/services/awards/internal/award-definitions.js +0 -0
  48. package/src/services/awards/internal/award-events.js +0 -0
  49. package/src/services/awards/internal/award-manager.js +0 -0
  50. package/src/services/awards/internal/certificate-builder.js +0 -0
  51. package/src/services/awards/internal/completion-data-generator.js +0 -0
  52. package/src/services/awards/internal/content-progress-observer.js +0 -0
  53. package/src/services/awards/internal/image-utils.js +0 -0
  54. package/src/services/awards/internal/message-generator.js +0 -0
  55. package/src/services/awards/internal/types.js +0 -0
  56. package/src/services/awards/types.d.ts +0 -0
  57. package/src/services/awards/types.js +0 -0
  58. package/src/services/config.js +0 -0
  59. package/src/services/content/artist.ts +0 -0
  60. package/src/services/content/content.ts +0 -0
  61. package/src/services/content/genre.ts +0 -0
  62. package/src/services/content/instructor.ts +0 -0
  63. package/src/services/content-org/content-org.js +0 -0
  64. package/src/services/content-org/guided-courses.ts +0 -0
  65. package/src/services/content-org/learning-paths.ts +0 -0
  66. package/src/services/content-org/playlists-types.js +0 -0
  67. package/src/services/content-org/playlists.js +0 -0
  68. package/src/services/content.js +0 -0
  69. package/src/services/contentAggregator.js +0 -0
  70. package/src/services/contentLikes.js +0 -0
  71. package/src/services/contentProgress.js +0 -0
  72. package/src/services/dataContext.js +0 -0
  73. package/src/services/dateUtils.js +0 -0
  74. package/src/services/eventsAPI.js +0 -0
  75. package/src/services/forums/categories.ts +0 -0
  76. package/src/services/forums/forums.ts +0 -0
  77. package/src/services/forums/posts.ts +0 -0
  78. package/src/services/forums/threads.ts +0 -0
  79. package/src/services/forums/types.ts +0 -0
  80. package/src/services/gamification/awards.ts +0 -0
  81. package/src/services/gamification/gamification.js +0 -0
  82. package/src/services/imageSRCBuilder.js +0 -0
  83. package/src/services/imageSRCVerify.js +0 -0
  84. package/src/services/liveTesting.ts +0 -0
  85. package/src/services/permissions/PermissionsAdapter.ts +0 -0
  86. package/src/services/permissions/PermissionsAdapterFactory.ts +0 -0
  87. package/src/services/permissions/PermissionsV1Adapter.ts +0 -0
  88. package/src/services/permissions/PermissionsV2Adapter.ts +0 -0
  89. package/src/services/permissions/README.md +0 -0
  90. package/src/services/permissions/index.ts +0 -0
  91. package/src/services/progress-events.js +0 -0
  92. package/src/services/progress-row/base.js +0 -0
  93. package/src/services/progress-row/rows/.indexignore +0 -0
  94. package/src/services/progress-row/rows/content-card.js +0 -0
  95. package/src/services/progress-row/rows/method-card.js +0 -0
  96. package/src/services/progress-row/rows/playlist-card.js +0 -0
  97. package/src/services/railcontent.js +0 -0
  98. package/src/services/recommendations.js +0 -0
  99. package/src/services/reporting/README.md +0 -0
  100. package/src/services/reporting/reporting.ts +0 -0
  101. package/src/services/reporting/types.ts +0 -0
  102. package/src/services/sanity.js +25 -52
  103. package/src/services/sentry/.indexignore +0 -0
  104. package/src/services/sentry/index.ts +0 -0
  105. package/src/services/sync/.indexignore +0 -0
  106. package/src/services/sync/adapters/factory.ts +0 -0
  107. package/src/services/sync/adapters/lokijs.ts +0 -0
  108. package/src/services/sync/adapters/sqlite.ts +0 -0
  109. package/src/services/sync/context/index.ts +0 -0
  110. package/src/services/sync/context/providers/base.ts +0 -0
  111. package/src/services/sync/context/providers/connectivity.ts +0 -0
  112. package/src/services/sync/context/providers/durability.ts +0 -0
  113. package/src/services/sync/context/providers/index.ts +0 -0
  114. package/src/services/sync/context/providers/session.ts +0 -0
  115. package/src/services/sync/context/providers/tabs.ts +0 -0
  116. package/src/services/sync/context/providers/visibility.ts +0 -0
  117. package/src/services/sync/database/factory.ts +0 -0
  118. package/src/services/sync/effects/index.ts +0 -0
  119. package/src/services/sync/effects/logout-warning.ts +0 -0
  120. package/src/services/sync/errors/boundary.ts +0 -0
  121. package/src/services/sync/errors/index.ts +0 -0
  122. package/src/services/sync/errors/validators.ts +0 -0
  123. package/src/services/sync/fetch.ts +0 -0
  124. package/src/services/sync/index.ts +0 -0
  125. package/src/services/sync/manager.ts +0 -0
  126. package/src/services/sync/models/Base.ts +0 -0
  127. package/src/services/sync/models/ContentLike.ts +0 -0
  128. package/src/services/sync/models/ContentProgress.ts +0 -0
  129. package/src/services/sync/models/Practice.ts +0 -0
  130. package/src/services/sync/models/PracticeDayNote.ts +0 -0
  131. package/src/services/sync/models/UserAwardProgress.ts +0 -0
  132. package/src/services/sync/models/index.ts +0 -0
  133. package/src/services/sync/repositories/base.ts +0 -0
  134. package/src/services/sync/repositories/content-likes.ts +0 -0
  135. package/src/services/sync/repositories/content-progress.ts +0 -0
  136. package/src/services/sync/repositories/index.ts +0 -0
  137. package/src/services/sync/repositories/practice-day-notes.ts +0 -0
  138. package/src/services/sync/repositories/practices.ts +0 -0
  139. package/src/services/sync/repositories/user-award-progress.ts +0 -0
  140. package/src/services/sync/repository-proxy.ts +0 -0
  141. package/src/services/sync/resolver.ts +0 -0
  142. package/src/services/sync/retry.ts +0 -0
  143. package/src/services/sync/run-scope.ts +0 -0
  144. package/src/services/sync/schema/index.ts +0 -0
  145. package/src/services/sync/serializers/index.ts +0 -0
  146. package/src/services/sync/serializers/model.ts +0 -0
  147. package/src/services/sync/serializers/raw.ts +0 -0
  148. package/src/services/sync/store/index.ts +0 -0
  149. package/src/services/sync/store/push-coalescer.ts +0 -0
  150. package/src/services/sync/store-configs.ts +0 -0
  151. package/src/services/sync/strategies/base.ts +0 -0
  152. package/src/services/sync/strategies/index.ts +0 -0
  153. package/src/services/sync/strategies/initial.ts +0 -0
  154. package/src/services/sync/strategies/polling.ts +0 -0
  155. package/src/services/sync/telemetry/flood-prevention.ts +0 -0
  156. package/src/services/sync/telemetry/index.ts +0 -0
  157. package/src/services/sync/telemetry/sampling.ts +0 -0
  158. package/src/services/sync/utils/event-emitter.ts +0 -0
  159. package/src/services/sync/utils/index.ts +0 -0
  160. package/src/services/sync/utils/throttle.ts +0 -0
  161. package/src/services/sync/utils/timers.ts +0 -0
  162. package/src/services/types.js +0 -0
  163. package/src/services/urlBuilder.ts +0 -0
  164. package/src/services/user/account.ts +5 -1
  165. package/src/services/user/chat.js +0 -0
  166. package/src/services/user/interests.js +0 -0
  167. package/src/services/user/management.js +0 -0
  168. package/src/services/user/memberships.ts +0 -0
  169. package/src/services/user/notifications.js +0 -0
  170. package/src/services/user/onboarding.ts +0 -0
  171. package/src/services/user/payments.ts +0 -0
  172. package/src/services/user/permissions.js +0 -0
  173. package/src/services/user/profile.js +0 -0
  174. package/src/services/user/sessions.js +0 -0
  175. package/src/services/user/types.d.ts +0 -0
  176. package/src/services/user/types.js +0 -0
  177. package/src/services/user/user-management-system.js +0 -0
  178. package/src/services/userActivity.js +0 -0
  179. package/test/HttpClient.test.js +0 -0
  180. package/test/awards/award-alacarte-observer.test.js +0 -0
  181. package/test/awards/award-auto-refresh.test.js +0 -0
  182. package/test/awards/award-calculations.test.js +0 -0
  183. package/test/awards/award-certificate-display.test.js +0 -0
  184. package/test/awards/award-collection-edge-cases.test.js +0 -0
  185. package/test/awards/award-collection-filtering.test.js +0 -0
  186. package/test/awards/award-completion-flow.test.js +0 -0
  187. package/test/awards/award-exclusion-handling.test.js +0 -0
  188. package/test/awards/award-multi-lesson.test.js +0 -0
  189. package/test/awards/award-observer-integration.test.js +0 -0
  190. package/test/awards/award-query-messages.test.js +0 -0
  191. package/test/awards/award-user-collection.test.js +0 -0
  192. package/test/awards/duplicate-prevention.test.js +0 -0
  193. package/test/awards/helpers/completion-mock.js +0 -0
  194. package/test/awards/helpers/index.js +0 -0
  195. package/test/awards/helpers/mock-setup.js +0 -0
  196. package/test/awards/helpers/progress-emitter.js +0 -0
  197. package/test/awards/message-generator.test.js +0 -0
  198. package/test/content.test.js +0 -0
  199. package/test/contentLikes.test.js +0 -0
  200. package/test/contentProgress.test.js +0 -0
  201. package/test/dataContext.test.js +0 -0
  202. package/test/forum.test.js +0 -0
  203. package/test/imageSRCBuilder.test.js +0 -0
  204. package/test/imageSRCVerify.test.js +0 -0
  205. package/test/initializeTests.js +0 -0
  206. package/test/learningPaths.test.js +0 -0
  207. package/test/lib/__snapshots__/filter.test.ts.snap +0 -0
  208. package/test/lib/filter.test.ts +0 -0
  209. package/test/lib/lastUpdated.test.js +0 -0
  210. package/test/lib/query.test.ts +0 -0
  211. package/test/live/contentProgressLive.test.js +0 -0
  212. package/test/live/railcontentLive.test.js +0 -0
  213. package/test/localStorageMock.js +0 -0
  214. package/test/log.js +0 -0
  215. package/test/logout.test.js +199 -0
  216. package/test/mockData/award-definitions.js +0 -0
  217. package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
  218. package/test/mockData/mockData_progress_content.json +0 -0
  219. package/test/mockData/mockData_sanity_progress_content.json +0 -0
  220. package/test/mockData/mockData_user_practices.json +0 -0
  221. package/test/notifications.test.js +0 -0
  222. package/test/progressRows.test.js +0 -0
  223. package/test/reporting.test.js +132 -0
  224. package/test/sanityQueryService.test.js +0 -0
  225. package/test/streakMessage.test.js +0 -0
  226. package/test/sync/adapter.ts +0 -0
  227. package/test/sync/initialize-sync-manager.js +0 -0
  228. package/test/sync/models/award-database-integration.test.js +0 -0
  229. package/test/user/permissions.test.js +0 -0
  230. package/test/userActivity.test.js +0 -0
  231. package/test_owned_navigate.js +74 -0
  232. package/tools/generate-index.cjs +0 -0
  233. package/tsconfig.json +17 -0
@@ -9,6 +9,7 @@ import {
9
9
  contentTypeConfig,
10
10
  DEFAULT_FIELDS,
11
11
  descriptionField,
12
+ difficultyStringField,
12
13
  filtersToGroq,
13
14
  getChildFieldsForContentType,
14
15
  getFieldsForContentType,
@@ -31,6 +32,7 @@ import {
31
32
  showsTypes,
32
33
  SONG_TYPES,
33
34
  SONG_TYPES_WITH_CHILDREN,
35
+ liveFields,
34
36
  } from '../contentTypeConfig.js'
35
37
  import { fetchSimilarItems, recommendations } from './recommendations.js'
36
38
  import { getSongType, processMetadata, ALWAYS_VISIBLE_TABS } from '../contentMetaData.js'
@@ -330,7 +332,7 @@ export async function fetchNewReleases(
330
332
  "instructor": ${instructorField},
331
333
  "artists": instructor[]->name,
332
334
  difficulty,
333
- difficulty_string,
335
+ ${difficultyStringField()},
334
336
  length_in_seconds,
335
337
  published_on,
336
338
  "type": _type,
@@ -368,7 +370,7 @@ export async function fetchUpcomingEvents(brand, { page = 1, limit = 10 } = {})
368
370
  "artists": instructor[]->name,
369
371
  "instructor": ${instructorField},
370
372
  difficulty,
371
- difficulty_string,
373
+ ${difficultyStringField()},
372
374
  length_in_seconds,
373
375
  published_on,
374
376
  "type": _type,
@@ -421,7 +423,7 @@ export async function fetchScheduledReleases(brand, { page = 1, limit = 10 }) {
421
423
  "instructor": ${instructorField},
422
424
  "artists": instructor[]->name,
423
425
  difficulty,
424
- difficulty_string,
426
+ ${difficultyStringField()},
425
427
  length_in_seconds,
426
428
  published_on,
427
429
  "type": _type,
@@ -961,9 +963,9 @@ export async function fetchLessonContent(railContentId, { addParent = false } =
961
963
  ${parentQuery}
962
964
  ...select(
963
965
  defined(live_event_start_time) => {
964
- "live_event_start_time": live_event_start_time,
965
- "live_event_end_time": live_event_end_time,
966
- "live_event_stream_id": live_event_stream_id,
966
+ live_event_start_time,
967
+ live_event_end_time,
968
+ live_event_stream_id,
967
969
  "vimeo_live_event_id": vimeo_live_event_id,
968
970
  "videoId": coalesce(live_event_stream_id, video.external_id),
969
971
  "live_event_is_global": live_global_event == true
@@ -1096,7 +1098,7 @@ export async function fetchSiblingContent(railContentId, brand = null) {
1096
1098
  }).buildFilter()
1097
1099
 
1098
1100
  const brandString = brand ? ` && brand == "${brand}"` : ''
1099
- const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, difficulty_string, artist->, "permission_id": permission_v2, "genre": genre[]->name, "parent_id": parent_content_data[0].id`
1101
+ const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, ${difficultyStringField()}, artist->, "permission_id": permission_v2, "genre": genre[]->name, "parent_id": parent_content_data[0].id`
1100
1102
 
1101
1103
  const query = `*[railcontent_id == ${railContentId}${brandString}]{
1102
1104
  _type, parent_type, 'parent_id': parent_content_data[0].id, railcontent_id,
@@ -1143,7 +1145,7 @@ export async function fetchRelatedLessons(railContentId) {
1143
1145
  { showMembershipRestrictedContent: true }
1144
1146
  ).buildFilter()
1145
1147
 
1146
- const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, difficulty_string, railcontent_id, artist->,"permission_id": permission_v2,_type, "genre": genre[]->name`
1148
+ const queryFields = `_id, "id":railcontent_id, published_on, "instructor": instructor[0]->name, title, "thumbnail":thumbnail.asset->url, length_in_seconds, status, "type": _type, difficulty, ${difficultyStringField()}, railcontent_id, artist->,"permission_id": permission_v2,_type, "genre": genre[]->name`
1147
1149
 
1148
1150
  const query = `*[railcontent_id == ${railContentId} && (!defined(permission) || references(*[_type=='permission']._id))]{
1149
1151
  _type, parent_type, railcontent_id,
@@ -1184,50 +1186,21 @@ export async function fetchLiveEvent(brand, forcedContentId = null) {
1184
1186
  )
1185
1187
  endDateTemp = new Date(endDateTemp.setMinutes(endDateTemp.getMinutes() - LIVE_EXTRA_MINUTES))
1186
1188
 
1187
- // See LiveStreamEventService.getCurrentOrNextLiveEvent for some nice complicated logic which I don't think is actually importart
1188
- // this has some +- on times
1189
- // But this query just finds the first scheduled event (sorted by start_time) that ends after now()
1190
- const query =
1189
+ const liveEventFields = liveFields + `, 'event_coach_calendar_id': coalesce(calendar_id, '${defaultCalendarID}')`
1190
+
1191
+ const baseFilter =
1191
1192
  forcedContentId !== null
1192
- ? `*[railcontent_id == ${forcedContentId} ]{
1193
- 'slug': slug.current,
1194
- 'id': railcontent_id,
1195
- live_event_start_time,
1196
- live_event_end_time,
1197
- live_event_stream_id,
1198
- vimeo_live_event_id,
1199
- railcontent_id,
1200
- published_on,
1201
- 'event_coach_url' : instructor[0]->web_url_path,
1202
- 'event_coach_calendar_id': coalesce(calendar_id, '${defaultCalendarID}'),
1203
- title,
1204
- "thumbnail": thumbnail.asset->url,
1205
- ${artistOrInstructorName()},
1206
- difficulty_string,
1207
- "instructors": ${instructorField},
1208
- 'videoId': coalesce(live_event_stream_id, video.external_id),
1209
- } | order(live_event_start_time)[0...1]`
1210
- : `*[status == 'scheduled' && brand == '${brand}' && defined(live_event_start_time) && live_event_start_time <= '${getSanityDate(startDateTemp, false)}' && live_event_end_time >= '${getSanityDate(endDateTemp, false)}']{
1211
- 'slug': slug.current,
1212
- 'id': railcontent_id,
1213
- live_event_start_time,
1214
- live_event_end_time,
1215
- live_event_stream_id,
1216
- vimeo_live_event_id,
1217
- railcontent_id,
1218
- published_on,
1219
- 'event_coach_url' : instructor[0]->web_url_path,
1220
- 'event_coach_calendar_id': coalesce(calendar_id, '${defaultCalendarID}'),
1221
- title,
1222
- "thumbnail": thumbnail.asset->url,
1223
- ${artistOrInstructorName()},
1224
- difficulty_string,
1225
- "instructors": instructor[]->{
1226
- name,
1227
- web_url_path,
1228
- },
1229
- 'videoId': coalesce(live_event_stream_id, video.external_id),
1230
- } | order(live_event_start_time)[0...1]`
1193
+ ? `railcontent_id == ${forcedContentId}`
1194
+ : `status == 'scheduled'
1195
+ && brand == '${brand}'
1196
+ && defined(live_event_start_time)
1197
+ && live_event_start_time <= '${getSanityDate(startDateTemp, false)}'
1198
+ && live_event_end_time >= '${getSanityDate(endDateTemp, false)}'`
1199
+
1200
+ const filter = await new FilterBuilder(baseFilter, {bypassPermissions: true}).buildFilter()
1201
+
1202
+ // This query finds the first scheduled event (sorted by start_time) that ends after now()
1203
+ const query = `*[${filter}]{${liveEventFields}} | order(live_event_start_time)[0...1]`
1231
1204
 
1232
1205
  return await fetchSanity(query, false, { processNeedAccess: false })
1233
1206
  }
@@ -2001,7 +1974,7 @@ export async function fetchScheduledAndNewReleases(
2001
1974
  ${artistOrInstructorName()},
2002
1975
  "artists": instructor[]->name,
2003
1976
  difficulty,
2004
- difficulty_string,
1977
+ ${difficultyStringField()},
2005
1978
  length_in_seconds,
2006
1979
  published_on,
2007
1980
  "type": _type,
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -4,6 +4,7 @@
4
4
  import { HttpClient } from '../../infrastructure/http/HttpClient'
5
5
  import { HttpError } from '../../infrastructure/http/interfaces/HttpError'
6
6
  import { globalConfig } from '../config.js'
7
+ import { clearAllCachedData } from '../dataContext.js'
7
8
  import { Onboarding } from './onboarding'
8
9
  import { AuthResponse } from './types'
9
10
 
@@ -149,7 +150,10 @@ export async function confirmEmailChange(token: string): Promise<void> {
149
150
  export async function deleteAccount(userId: number): Promise<void> {
150
151
  const apiUrl = `/api/user-management-system/v1/users/${userId}`
151
152
  const httpClient = new HttpClient(globalConfig.baseUrl, globalConfig.sessionConfig.token)
152
- return httpClient.delete(apiUrl)
153
+ await httpClient.delete(apiUrl)
154
+
155
+ // Clear all locally cached data to prevent data leakage between users
156
+ await clearAllCachedData()
153
157
  }
154
158
 
155
159
  /**
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/test/log.js CHANGED
File without changes