Skip to content

Latest commit

 

History

History
405 lines (392 loc) · 36.8 KB

CHANGELOG.md

File metadata and controls

405 lines (392 loc) · 36.8 KB

@samvera/ramp

v3.3.0 tag (02/12/2024)

  • Align CC btn in control bar with green border by @Dananji in #598
  • Use targetTouches in touch event to calculate progress updates by @Dananji in #600
  • Align structure highlight marker with hovered progress bar by @Dananji in #604
  • Force the media to load for iOS and Safari on desktop by @Dananji in #607
  • Fix broken captions button reference in handleCaptionChange() by @Dananji in #608
  • Start from custom manifest start by @masaball in #609
  • Default to empty string if manifest label is not present by @masaball in #621
  • Sanitize manifest url if params included in middle by @masaball in #623
  • Store captions on/off status in localstorage for session by @Dananji in #613
  • Display Video.js errors instead letting the player crash by @Dananji in #612
  • 3.2.1 patch by @Dananji in #617
  • Reveal player early on progress event with enough data for playback by @Dananji in #626
  • Limit time tooltip display offset to playable range width by @Dananji in #629
  • Fix player replaying last section/single section item in a loop by @Dananji in #628
  • Parsing refactor by @Dananji in #625
  • Zoom icons 596 by @Dananji in #619
  • React 18 upgrade by @Dananji in #633
  • Bump webpack from 5.76.2 to 5.94.0 by @dependabot in #631
  • Bump webpack-dev-middleware from 5.3.3 to 5.3.4 by @dependabot in #634
  • Limit re-renders for AutoAdvanceToggle, SupplementalFiles, and MarkersDisplay components by @Dananji in #640
  • Convert vjs components by @Dananji in #635
  • Make withCredentials work with videojs 7.x and 8.x by @mbklein in #642
  • Remove node-18 and add node-22 to CircleCI by @Dananji in #641
  • Remove useMemo in component export, refactor MetadataDisplay component by @Dananji in #646
  • State management refactor for structure by @Dananji in #643
  • Custom hook for state management in Transcript component by @Dananji in #652
  • Custom hook for MediaPlayer and VideoJSPlayer handling by @Dananji in #647
  • Bump rollup from 2.79.1 to 2.79.2 by @dependabot in #651
  • Bump tough-cookie from 4.1.2 to 4.1.4 by @dependabot in #654
  • Add comments, cleanup Videojs component options, use cx lib to build classnames by @Dananji in #653
  • Fix skipped tests for useLocalStorage by @Dananji in #655
  • Update player in Ramp demo site when using 'Set Manifest' by @Dananji in #661
  • Fix minor bugs in player introduced in refactor/cleanup work by @Dananji in #662
  • Move captions above controls when user is active by @Dananji in #665
  • Refine progress-bar by using VideoJS' native ProgressControl by @Dananji in #664
  • Remove cyclical dependence of SectionHeading and List by @Dananji in #668
  • Replace volume control with muteToggle/volumePanel, popup menus above progress-bar by @Dananji in #669
  • Adjust progress-bar spacing to display menus above it by @Dananji in #670
  • Collapse/expand sections button by @Dananji in #671
  • Bump http-proxy-middleware from 2.0.6 to 2.0.7 by @dependabot in #683
  • Change min-width and min-height of the player for iOS by @Dananji in #684
  • Regression bug: display error for empty Manifest w/o crashing by @Dananji in #685
  • Change UI for structured nav to include collapse all button by @Dananji in #686
  • Create inaccessible message interval only in a single custom hook by @Dananji in #690
  • Fix a11y issues found with Siteimprove, WAVE, and Axe by @Dananji in #691
  • Fix sections UI for non-collapsible structures by @Dananji in #692
  • Wrap long labels w/o spaces in structure to new lines by @Dananji in #693
  • Extend player min-width to Android browsers by @Dananji in #696
  • Center align progressbar in audio, and add padding by @Dananji in #697
  • Increase progress-bar height, remove hover animation by @Dananji in #699
  • Show timetool-tip above search marker when hovering by @Dananji in #702
  • Specify player's min-height for audio in mobile browsers by @Dananji in #703
  • Force player to load in Safari and iOS browsers by @Dananji in #707
  • Update progress-bar CSS on fullscreen exit in iOS by @Dananji in #708
  • Call player.load() in Safari/iOS browsers before calling play() by @Dananji in #709
  • Use control-bar width to add padding to progress-bar on sides by @Dananji in #715
  • Restrict setting player time when markers are outside of playable range by @Dananji in #716
  • Remove progress-bar shadow on focus by @Dananji in #721
  • Prevent playhead from jumping to end of progress bar by @masaball in #725
  • Trigger ended event when end = duration by @Dananji in #722
  • Add back tracks upon quality selection by @Dananji in #720
  • Change order of player.load() and setting isReady to keep markers by @Dananji in #726
  • Fix collapse/expand all button behavior with each section status change by @Dananji in #729
  • Invoke handleTimeupdate to update markers on player reload by @Dananji in #735
  • Explicitly update played range by @Dananji in #733
  • Remove space between control-bar pseudo elements, to mouse display on hover by @Dananji in #737
  • Update README for 3.3.0 release by @Dananji in #745

v3.2.1 tag (08/09/2024)

  • Set accurate duration on progress bar creation by @Dananji in #616

v3.2.0 tag (07/30/2024)

  • Auto scroll active transcript cue to the top by @Dananji in #449
  • Bump express from 4.18.2 to 4.19.2 by @dependabot in #465
  • Display a message for empty manifests without crashing by @Dananji in #475
  • Adjust marker display on UI when end > canvas duration by @Dananji in #471
  • Build active structure item classname into a single line by @Dananji in #478
  • Bump tar from 6.1.13 to 6.2.1 by @dependabot in #479
  • Only display rendering files in the supplemental files component by @Dananji in #474
  • Upgrade Video.js to v8.10.0 by @masaball in #453
  • Skip combination keypresses in player hotkeys by @Dananji in #481
  • Rights metadata by @Dananji in #480
  • Videojs setup rework by @Dananji in #460
  • Vtt parse fix by @Dananji in #476
  • Add playback rate support for media player by @Dananji in #477
  • Bump gh-pages from 4.0.0 to 5.0.0 by @dependabot in #482
  • Fix track scrubber bugs in Videojs re-setup work by @Dananji in #484
  • Update version and CHANGELOG to reflect changes in latest release and tags by @Dananji in #485
  • Improve structured navigation user experience by @Dananji in #483
  • Wrap overflowing metadata text into new lines to avoid horizontal scroll by @Dananji in #490
  • Set player container aspect ratio to 16:9 for blank canvas messages by @Dananji in #491
  • Don't include 2nd bundled copy of css on demo page. Resolves #487 by @patrick-lienau in #488
  • Accessibility fixes to issues found in axe report by @Dananji in #493
  • Remove CSS classes for captions, fix CSS for placeholder canvas messages by @Dananji in #495
  • Transcript Search Functionality by @patrick-lienau in #497
  • Update Node in Circle-CI by @Dananji in #506
  • Update structure parsing to include root-level Range in display by @Dananji in #496
  • Fix a couple of minor bugs by @Dananji in #507
  • Enable/disable captions icon as needed when switching between canvases by @Dananji in #505
  • Fix seeking in safari by @Dananji in #504
  • Fix Ramp crashing when a SRT transcript is selected by @Dananji in #511
  • Update transcript search styling by @Dananji in #510
  • Fix a couple of demo data bugs by @Dananji in #512
  • Content search by @Dananji in #515
  • Render time offsets for cues that begin exactly at 0 by @cjcolvar in #521
  • showNotes Transcript prop for displaying NOTE comments (default: false) by @cjcolvar in #520
  • Improve VTT parsing by @cjcolvar in #518
  • Handle case when some transcripts have hits but others do not by @cjcolvar in #522
  • Mobile icons by @Dananji in #527
  • Native player by @Dananji in #531
  • Display previous/next buttons and timer for inaccessible canvases by @Dananji in #529
  • Adjust text highlight color for contrast in transcript search by @Dananji in #533
  • Preserve captions off state in native iOS player on play event by @Dananji in #534
  • Scroll transcript search hits within container by @Dananji in #535
  • Adjust content search when switching between transcripts by @Dananji in #532
  • Bump ws from 6.2.2 to 6.2.3 by @dependabot in #528
  • Use a debounce timer for content search request by @Dananji in #544
  • SRT/VTT timestamp validation to deny single digit hour in hh:mm... by @Dananji in #546
  • Fix parsing for timestamps with commas as decimal seperators by @Dananji in #545
  • Untimed search by @Dananji in #542
  • Use flexbox instead of grid to arrange transcript menu by @Dananji in #547
  • Update setTimeout in the debounce by @Dananji in #550
  • Remember active caption selection by @Dananji in #549
  • Fix previous/next button functionality with inaccessible item transitions by @Dananji in #553
  • Fix for multiple captions being selected in captions menu by @Dananji in #555
  • Fix prev/next button bugs in mobile devices by @Dananji in #554
  • Text search nav by @Dananji in #558
  • Add a title bar linking to external source to video player by @masaball in #557
  • Do not display timer when last item is inaccessible by @Dananji in #563
  • Add Thirdwave as a contributor by @Dananji in #541
  • Small tweak to top margin of horizontal volume slider thumb by @cjcolvar in #562
  • Fix grey overlay bug and related bugs in playlist item transitions by @Dananji in #565
  • Update no results message in transcript search by @masaball in #568
  • Ensure autoplay of next section when selecting inaccesible item by @masaball in #569
  • Fix regex to identify matches in content search response by @Dananji in #566
  • Fix split query bug in altReplace func by @Dananji in #570
  • Fix slow search by handling timing of updates and cache by @Dananji in #571
  • Check if manfiestState exists for search service parsing by @Dananji in #572
  • Update canvas duration on ready event by @Dananji in #573
  • Change vertical-align CSS for SVG by @Dananji in #574
  • Add withCredentials option to MediaPlayer component by @mbklein in #576
  • Read duration from either options or player property in progressbar by @Dananji in #578
  • Improve scrubbing and seeking by providing more space for scrubber and progress bar by @Dananji in #579
  • Allow progress bar updates with playback for audio in iOS by @Dananji in #584
  • Only reset isClicked if active structure item is set by @cjcolvar in #592
  • Vertical align lock icon for restricted struct items by @Dananji in #589
  • After an inaccessible item play the next item if user has started playback by @Dananji in #581
  • Update current time in audio player in iOS context by @Dananji in #595
  • Set accurate duration on progress bar creation by @Dananji in #594
  • Improve scrubbing in Safari with throttle and debounce on update events by @Dananji in #597
  • Update variables in progress component to refs to maintain accuracy with canvas updates by @Dananji in #587
  • Bug fix in desktop Safari scrubbing introduced in #597 by @Dananji in #603

v3.1.3 tag (04/10/2024) -> (This is not a Release in NPM)

  • Build active structure item classname into a single line by @Dananji in #478

3.1.2 (04/09/2024)

  • Adjust marker display on UI when end > canvas duration by @Dananji in #471

3.1.0 (04/04/2024)

  • Bump ip from 1.1.8 to 1.1.9 by @dependabot in #425
  • Parse playlist homepage as positional urls into structure links by @Dananji in #424
  • Interpret null values in metadata as empty strings by @Dananji in #427
  • Test audiannotate by @Dananji in #426
  • Use caption label in menu, not filename by @masaball in #439
  • Change caption filtering to always use VideoJS' tracks instead of HLS tracks by @Dananji in #428
  • Fix auto advance and player crashing on Canvas change by @Dananji in #432
  • Use alternate CSS properties to set the Canvas message height by @Dananji in #435
  • Only display CC button for Video instances by @Dananji in #438
  • Bump sanitize-html from 2.10.0 to 2.12.1 by @dependabot in #442
  • Prevent iOS rejected promise from raising error boundary by @masaball in #444
  • Omit active tab navigation with left/right key events in hotkeys by @Dananji in #445
  • Add SRT support in Transcript component by @Dananji in #446
  • Fix active structure items blinking with user interactions by @Dananji in #447
  • Fix Video.js custom components crashing when initializing by @Dananji in #448
  • Update 'Scroll for More' message when StuctNav is resized by @masaball in #450
  • Remove HLS caption handling by @Dananji in #443
  • Bump follow-redirects from 1.15.4 to 1.15.6 by @dependabot in #454
  • Fix multiple captions being selected on initial load by @Dananji in #455
  • Remove track.off('change') for unknown cc in iOS context by @Dananji in #456
  • Prevent structure items getting highlighted for inaccessible items by @Dananji in #459
  • Display timespans past duration as links in StructuredNavigation by @Dananji in #463

3.0.0 (02/19/2024)

  • Fix UI for file download and fix bug in quality selector by @Dananji in #160
  • Use placeholderCanvas to render poster image by @Dananji in #170
  • Fix repo name references with repo rename by @Dananji in #171
  • Add previous/next section buttons to player icons by @Dananji in #188
  • Avalon related fixes by @Dananji in #177
  • Fix bug when switching canvas using previous/next buttons by @Dananji in #193
  • Fix prod data manifests to work with multiple domain names by @Dananji in #195
  • Metadata component by @Dananji in #192
  • UI updates to Ramp media player and videojs by @Dananji in #199
  • Add Styleguidist docs for MediaPlayer component by @Dananji in #200
  • Restructure by @Dananji in #201
  • Bug fix for canvas target resolution by @Dananji in #203
  • Bump semver from 5.7.1 to 5.7.2 by @dependabot in #204
  • Machine generated transcripts by @Dananji in #194
  • Bump word-wrap from 1.2.3 to 1.2.4 by @dependabot in #208
  • Supplemental files by @cjcolvar in #206
  • Accessibility improvements by @Dananji in #209
  • Fix VideoJS file download bug by @Dananji in #211
  • Transcripts fix by @Dananji in #216
  • Bump @adobe/css-tools from 4.2.0 to 4.3.1 by @dependabot in #221
  • Add top level auto-advance toggle component. by @cjcolvar in #218
  • Fix color contrast in links by @Dananji in #224
  • Markers firstpass by @Dananji in #220
  • Add handling for empty canvases within playlist manifests by @masaball in #219
  • Fix color contrast for links when hovered by @Dananji in #230
  • Fix broken scrubbing due to time tooltip styling by @Dananji in #231
  • Player respects auto advance toggle by @cjcolvar in #242
  • Add check for empty item to getItemId by @masaball in #243
  • Fix player css for zooming in demo site by @Dananji in #248
  • Add i18n support with language optin in VideoJS by @Dananji in #235
  • Handle case when range only has a single canvas child by @cjcolvar in #241
  • Replace videojs-hotkeys with builtin hotkeys function by @masaball in #250
  • Make the volume slider horizontal and sticky for audio player by @Dananji in #251
  • Add marker component by @cjcolvar in #245
  • Set no-auto-advance as default behavior in the player by @Dananji in #253
  • Latest build without dynamic imports for VideoJS languages by @Dananji in #255
  • Remove Avalon-Api-Key field from request by @Dananji in #256
  • StructuredNavigation UI for redesign by @Dananji in #240
  • Prevent retrieving currentTime when player is disposed by @masaball in #257
  • Center big play button on zoom by @Dananji in #262
  • New build by @cjcolvar in #264
  • Supplemental file display both Canvas and Manifest files independently by @Dananji in #266
  • Only prevent event default on hotkey actions by @masaball in #267
  • Make canvas-level items w/o mediafragment into spans instead of buttons by @Dananji in #268
  • Fix missing player for prev/next btns, getMediaFragment error for undefined URIs by @Dananji in #270
  • Bump @babel/traverse from 7.21.3 to 7.23.2 by @dependabot in #271
  • Add active section by @Dananji in #275
  • Fix structure auto scrolling by @Dananji in #276
  • Fix mismatching colors for button and span section items in structure by @Dananji in #278
  • Fix missing canvas console error by @masaball in #279
  • Add scrollbar override to enable constant display by @masaball in #282
  • Display placeholder canvas message for all empty manifests by @Dananji in #277
  • Fix structure display for section items with Canvas references by @Dananji in #284
  • Make tab labels focusable in the demo site by @Dananji in #286
  • Keep focus on next/previous buttons when using keyboard navigation by @Dananji in #285
  • Error boundary by @Dananji in #291
  • Display tracker when displaying playlist manifests by @Dananji in #292
  • Setting restricted message timer when using autoplay by @Dananji in #300
  • Use full relative path to lang json files and configure rollup for dynamic json imports by @cjcolvar in #297
  • Fix keyboard navigation for the tabbed view in demo site by @Dananji in #301
  • Bump @adobe/css-tools from 4.3.1 to 4.3.2 by @dependabot in #302
  • Initialize display timer always when autoplay is ON by @Dananji in #304
  • Transcript scroll fix by @Dananji in #306
  • Enable native text track behavior overriding default in VideoJS by @Dananji in #307
  • Player icon width, big-play button, demo site CSS changes for responsive UI by @Dananji in #314
  • Scroll active structure item into view within the component by @Dananji in #313
  • Display a message for unsupported transcript file formats by @Dananji in #312
  • Change canvas change trigger from a mutation observer to an event listener by @masaball in #305
  • Retrieve and use CSRF token in Marker component by @masaball in #315
  • Only add captions button to VideoJS when the IIIF Manifest has tracks by @Dananji in #318
  • Canvas metadata by @Dananji in #311
  • Fix autoscroll for structurednav, move autoscroll out to a utility function by @Dananji in #324
  • Show generic error message when manifest request fails by @Dananji in #323
  • Increase Default Timeout by @joncameron in #317
  • Add 2 new props to set start canvas and time, and map them to start property behavior from a IIIF Manifest by @Dananji in #322
  • Fix autoplay breaking when the last item is restricted by @Dananji in #327
  • Reduce media height by @masaball in #328
  • Use listener for hotkey support instead of VideoJS hotkeys by @masaball in #326
  • Add touch support for player actions to support Android browsers by @masaball in #329
  • Track scrubber by @Dananji in #330
  • Primarily rely on browser for file extension assignment by @masaball in #319
  • Disable update of custom timer and progress bar in iOS context by @masaball in #336
  • Remove no markers message in MarkersDisplay component by @Dananji in #333
  • Bump follow-redirects from 1.15.2 to 1.15.4 by @dependabot in #337
  • Remove id attributes from svg elements and condense g elements by @cjcolvar in #341
  • Add safe navigation and fallback in case there aren't any canvases in manifest by @cjcolvar in #344
  • Some accessibility fixes by @cjcolvar in #340
  • Provide test:debug script alias that makes it easy to debug with any dev tools by @cjcolvar in #345
  • Filter duplicated captions instead of switching off native text track behavior in VideoJS by @Dananji in #353
  • Read canvas summary and render as data attribute alongside label by @cjcolvar in #350
  • Add fade out and message to indicate scrolling of structured nav by @masaball in #348
  • Fix breaking hotkeys after switching Canvas by @Dananji in #359
  • Fix playback issues in Safari by @Dananji in #356
  • Fix next Canvas button click by @Dananji in #358
  • Display transcript content on first load by @Dananji in #360
  • Fix scale for section buttons, to match with other player icons by @Dananji in #361
  • Add padding to playlist structure nav by @Dananji in #364
  • Make CSS for scrolling in structure work with adjustable height in host apps by @Dananji in #365
  • Improve handling of download filenames in Transcript and Supplemental File components by @masaball in #362
  • Give transcript items "role=listitem" attribute by @masaball in #368
  • Override Safari's native text track functionality by @Dananji in #367
  • Replace pointer handlers for transcript auto-scroll check with a checkbox by @Dananji in #371
  • Fix playback and transcript scroll for mobile/tablet devices by @Dananji in #369
  • Remove fade from StructNav by @masaball in #373
  • Stick scroll to see more text into one line by @Dananji in #374
  • Use touchpoints instead of iPad regex to detect iPads by @Dananji in #376
  • Disable volume slider for mobile devices by @masaball in #378
  • Fix hotkeys when focused on VideoJS's native controls by @Dananji in #380
  • Remove transition when horizontal volume becomes inactive by @masaball in #381
  • Force initialization of canvas to start time specified in manifest when canvas index changes by @cjcolvar in #386
  • Disable time updates when media has ended by @masaball in #389
  • Only force canvases to start from begining in playlist contexts by @Dananji in #388
  • Revert to label so toggling works and include aria-labelledby by @cjcolvar in #391
  • Remove z-index for player control bar in mobile devices, add an additional check for inactivity by @Dananji in #392
  • Show track scrubber in playlist context by @Dananji in #387
  • Add key to track map in VideoJS initializer by @masaball in #393
  • Assign id value to empty VideoJS instance by @masaball in #397
  • Update autoadvancetoggle component styleguidist docs by @Dananji in #398
  • Check if player is paused before firing ended events by @masaball in #403
  • Use localStorage to make volume and quality settings sticky by @cjcolvar in #395
  • Show captions in native player in iOS by @Dananji in #396
  • Fix broken hotkeys when switching Canvas and for mute in Chrome by @Dananji in #409
  • Force text track font size in mobile contexts by @masaball in #411
  • Make muted be a sticky setting by @cjcolvar in #414
  • Fix fullscreen crashing in Safari in iPad on iOS 17 by @Dananji in #412
  • Fix samples for transcripts docs in Styleguidist by @Dananji in #416
  • Use safe navigator when setting quality by @masaball in #417
  • Override VJS caption font to prevent double spacing by @masaball in #418
  • iOS double captions fix by @Dananji in #415
  • Fix sticky mute when switching from video to audio in mobile by @Dananji in #419
  • README updates by @Dananji in #421

2.0.0 (03/20/2023)

  • Renamed component library (#158)
  • Caption support (#155)
  • Update demo site description
  • Add queryparam support in demo, to work with IIIF cookbook recipes (#153)
  • Fix failing tests and webpack config (#152)
  • Demo site (#151)
  • Fix minor bugs in structure nav and file download (#143)
  • Bump dependencies (#142)
  • File download component (#132)
  • Fix player and time tooltip difference (#131)
  • Show structure in player when using structure nav (#130)
  • Fix webvtt parser (#129)
  • Test progress bar (#128)
  • Update README.MD (#126)
  • Fixed demo content (#125)
  • Fix error in console when switchin canvases (#119)
  • Parse 'start' prop in manifests, render accordingly in all components (#107)

@samvera/iiif-react-media-player

1.2.1 (12/23/2021)

  • 1.2.1
  • Build files for v1.2.1
  • Fix dependencies
  • Code cleanup (#112)
  • Add txt/vtt mime-type to parser
  • Change parser to use http response info to distinguish file types (#111)
  • Fix CSS for word document view
  • Use mammoth to parse .doc to html, remove GDrive viewer (#106)
  • Fix WebVTT parser (#105)
  • URL validation regex change
  • Change feedback for invalid transcript files (#102)
  • Add poster image for video player (#100)
  • Remove time tooltip over playhead (#99)

1.2.0 (10/12/2021)

  • 1.2.0
  • Build files for v1.2.0
  • Refine input checks before parsing (#98)
  • Use annotations instead of rendering in parser (#97)
  • Scope CSS (#96)
  • Fixes from beta.0 (#95)
  • Transcript parser ($94)
  • Display text transcripts (#92)
  • Fixed styling and docs built for demo page (#88)
  • Fix to include each component stylesheet into shipped package
  • Wire transcpt (#87)
  • Transcript UI implementation (#86)
  • Hotkeys enabled via videojs-hotkeys plugin (#85)

1.1.0 (05/21/2021)

  • Build files for v1.1.0 release and updated package.json
  • Minor fixes and dependency clean up (#81)
  • Add css to show nested structure properly (#79)
  • Change manifest parsing for caption files (#77)
  • Change audio player UI (#74)
  • Add quality selector (#68)
  • Improve timerail highlight (#62)
  • Add instructions to static demo page for using external manifest URLs (#61)
  • Update readme to add video.js to consuming application
  • General config and dependency fixes (#55)
  • Add caption (#54)
  • Fix markers for navigation across canvases (#53)
  • Fix for failing navigation when same item is clicked twice (#52)
  • Bug fixes when switching the player (#51)
  • Update markers styling (#49)
  • Fix playhead z-index and marker tooltip (#46)
  • Player switch for different types of media (#47)
  • Make audio player smaller, and player responsive (#45)
  • Structure nav (#44)
  • Example of how to add a custom control as a Class to the player (#41)
  • Indicate active structured navigation (#40)
  • Customized control bar for the player (#39)
  • Removes the duplicate instantiations of player caused by startTime endTime useEffect() (#38)
  • Highlight timefragment on player (#37)
  • Support moving playhead on videojs (#35)
  • VideoJS initial wire up (#34)
  • Start/offset support for media (#32)
  • Add Scss pattern (#31)
  • Fix failing tests and CircleCI integration (#30)
  • Update packaging for NPM (#26)
  • Add support for manifest prop (#27)
  • Remove Axios (#25)
  • Fix structural navigation (#14)