0.1.8 ā€¢ Published 9 months ago

@mycujoo/mcls-components v0.1.8

Weekly downloads
-
License
ISC
Repository
-
Last release
9 months ago

React MCLS components library


šŸ“Œ Deprecation Notice This version of the library is deprecated. We advise you to use the new components:


A library of configurable components for MyCujoo Live Services Platform

Installation

MCLS components library uses a Universal Module Definition so you can use it in NPM.

npm install @mycujoo/mcls-components or yarn add @mycujoo/mcls-components

The package requires: react, react-dom, @emotion/react to be also installed if not already present.

Dev notes

This library uses two private npm packages that require access. First one is for MyCujoo's private npm packages, this can be retrieved from npm after getting access: https://www.npmjs.com/settings/USERNAME/tokens. The second token can be retrieved from https://buf.build/settings/user. After getting both make them available as environment variables: NPM_TOKEN and BUF_TOKEN. Use either of the two methods

Open command line and run:

nano ~/.zshrc
# Scroll to the bottom of the file and add the following line to set your environment variables
# export NPM_TOKEN=YOUR_NPM_TOKEN
# export BUF_TOKEN=YOUR_BUF_TOKEN
# Save and close

Or

export NPM_TOKEN=YOUR_NPM_TOKEN
export BUF_TOKEN=YOUR_BUF_TOKEN

Basic Use

For full components documentation please check Storybook.

Player

To use the react player import Player from the library and pass at least a valid MCLS eventId and you MCLS publicKey

import { Player } from '@mycujoo/player-components'

<Player
  eventId= 'EVENT_ID'
  publicKey= 'PUBLIC_KEY'
  identityToken=''
  autoplay
  debug
  showInfoButton
  showLiveViewers
  showSeekbar
  showFullscreen
  showBackForwardButtons
  showQualitySelector
  showVolume
  showTimers
  showChromecast
  showPictureInPicture
  enableAnnotations
  analyticsType= 'youbora'
  lang= 'en'
  analyticsAccount=''
  analyticsUserId=''
  defaultVolume={0}
  startPosition={0}
  seekTo={0}
  totalViewers={0}
  customPlaylistUrl=''
  adUnit=''
  adCustParams = 'age_category=u19&id_channel=6486&logged_in=1'
  className=''
  analyticsCustomParams= {
    customParam1: 'test p1',
    customParam3: 'test p3',
    customParam4: 'test p4',
    customParam5: 'test p5',
    customParam6: 'test p6',
    customParam7: 'test p7',
  }
  globalStyle={globalStyle}
  onTimeUpdate={action('onTimeUpdate')}
  onGetTitle={action('onGetTitle')}
  onGetEvent={action('onGetEvent')}
  onVideoPlay={action('onVideoPlay')}
  onVideoFirstPlay={action('onVideoFirstPlay')}
  onLoadedMetadata={action('onLoadedMetadata')}
  onVideoPause={action('onVideoPause')}
  onVideoEnd={action('onVideoEnd')}
  onMediaControlChange={action('onMediaControlChange')}
  onFullscreenChange={action('onFullscreenChange')}
  onPlayerViewChange={action('onPlayerViewChange')}
  onGetMetadata={action('onGetMetadata')}
  onPlayerInitialize={action('onPlayerInitialize')}
  onAdsBreakStart={action('onAdsBreakStart')}
  onAdStart={action('onAdStart')}
  onAdSkip={action('onAdSkip')}
  onAdComplete={action('onAdComplete')}
  onAdsBreakComplete={action('onAdsBreakComplete')}
  onAdsManager={action('onAdsManager')}
  onQualityChange={action('onQualityChange')}
  onWaiting={action('onWaiting')}
  onSeeked={action('onSeeked')}
  onSeeking={action('onSeeking')}
  >
    <div>Injected content</div>
  </Player>

In order IMA ads to play IMA SDK scripts needs to be loaded on the page where the Player is used. For chromecast to be available the cast sender framework needs to be loaded on the page. For ad annotations to fill in, GPT library needs to be loaded on the page.

<script
  async
  src="//imasdk.googleapis.com/js/sdkloader/ima3.js"
  id="googleIMASdk"
></script>
<script
  async
  src="//gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"
  id="googleCastFramework"
></script>
<script
  async
  src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"
></script>

For more details on all the available options of the player configuration go to Player component documentation.

AdSlot

To use the react ad unit import AdSlot from the library and pass at least unitPath and sizeMapping props.

import { AsSlot } from '@mycujoo/player-components'

;<AsSlot
  unitPath={'/6355419/Travel/Europe'}
  targeting={{
    name: 'name',
  }}
  sizeMapping={[
    {
      viewport: [0, 0],
      slot: [[728, 90]],
    },
    {
      viewport: [900, 0],
      slot: [
        [1024, 768],
        [750, 200],
      ],
    },
  ]}
  slotRefreshRate={60000}
/>

In order for GPT ads to work the gpt library must be loaded on the pages where the AdSlots are used.

<script
  async
  src="https://securepubads.g.doubleclick.net/tag/js/gpt.js"
></script>
  • useAdsEvents hook. For implementing custom logic around adSlots on a page this hook can be used. The hook handles subscriptions to Ad events listeners in a react hook. Below is an example of extending the hook to manage hiding some low priority ads from the page when ads with a higher priority are being shown.
import { useAdEvents } from '@mycujoo/player-components'

export const useLowPriorityAdsHandler = (): void => {
  const [adUnits] = useState(new Map<string, googletag.Slot>())

  useAdsEvents({
    onSlotLoad: (unitPath, unit) => {
      adUnits.set(unitPath, unit)
    },
    onSlotVisibilityChange: (unitPath, _unit, visualViewport) => {
      if (unitPath === '/test/ad/path') {
        const lowPriorityAd = adUnits.get('/test/ad/low/prio/path')
        if (visualViewport > 0) {
          lowPriorityAd && window?.googletag?.destroySlots([lowPriorityAd])
        }
      }
    },
  })
}
MCLS Events Slider

To use the MCLS events slider import MCLSEventsSlider from the library and pass at least your publicKey, a valid jsx card component and a type ('upcoming', 'live', 'past' or 'featured'). The type 'featured' is available for cases in which a predefined list of events needs to be displayed, in which case, the event IDs are passed through featuredEvents. For other slider types featuredEvents will be ignored.

MCLSEventsSlider handles the fetching of events from MCLS api's and uses the data agnostic Slider, passing the event data as data to each card. This Slider component is available for more advanced screnarios where a custom data-fetching wrapper might be preferred.

Visual configuration options of the slider are passed through a config object where arrows, title, and general slider layout can be customized.

import { MCLSEventsSlider, MatchCard } from '@mycujoo/mcls-components'

;<MCLSEventsSlider
  publicKey={'YOUR_PUBLIC_KEY'}
  lang={'en'}
  config={{
    title: {
      align: 'left',
      color: '#FFF',
      fontFamily: 'inherit',
      uppercase: true,
      underline: false,
      size: '12',
      weight: '500',
    },
  }}
  maxCards={20}
  type="featured"
  featuredEvents={['eventId1']}
  card={
    <MatchCard
      fallbackData={{
        metadata: { league_name: 'League Name A' },
        thumbnail_url:
          'https://mycujoo-assets-fastly.images.mcls.live/theme-fifa%2B/fall-background-test.svg',
      }}
      dataPaths={dataPathsObj}
      onClick={onOpenEvent}
      config={{
        size: 'l',
        primaryColor: '#F12D4B',
        secondaryColor: '#02102a',
        thumbnail: {
          viewers: false,
        },
        showTag: true,
        borderRadius: 5,
        action: {
          buttonConfig: {
            position: 'left',
          },
        },
      }}
    />
  }
/>
MCLS Events Grid

To use the MCLS Events Grid import MCLSEventsGrid from the library and pass at least your publicKey, a valid jsx card component, and a type ('upcoming', 'live', 'past' or 'featured'). The type 'featured' is available for cases in which a predefined list of events needs to be displayed, in which case, the event IDs are passed through featuredEvents.

MCLSEventsGrid handles the fetching of events from MCLS api's and uses the data agnostic CardsGrid, passing the event data as data to each card. This CardsGrid component is available for more advanced screnarios where a custom data-fetching wrapper might be preferred.

MCLSEventsGrid component includes logic for infinite scrolling of cards on the the grid when the type is other than 'featured'.

import { MCLSEventsGrid, MatchCard } from '@mycujoo/mcls-components'

;<MCLSEventsGrid
  publicKey={'YOUR_PUBLIC_KEY'}
  title="Upcoming events"
  titleLeftComponent={<Button>Your custom button</Button>}
  type="upcoming"
  lang="de"
  config={{
    layout: {
      gutter: 15,
      marginTop: 20,
    },
  }}
  card={
    <MatchCard
      dataPaths={dataPathsObj}
      onClick={handleCardClick}
      config={{
        size: 'm',
        borderRadius: 8,
        thumbnail: {
          icon: true,
          viewers: true,
        },
        primaryColor: '#f12d4b',
        showTag: true,
      }}
    />
  }
/>

Cards components

Cards are a set of highly configurable components that are available to be used and passed to sliders, grids or columns. Each card is meant to be better suited for a different purpose, design or event type.

Match Card

This card is intended to be used for Match-type events where there is or will be a score.

MatchCard receives data object directly from the parent slider, grid or column.

It requires to be passed at least dataPaths object which maps the path from the event data object to the different fields that are displayed (team names, scores, logos, event start time, id, etc). Clicking on the card may be handled through a function passed as onClick or as a <a> HTML element. href value for the card is provided through hrefBasePath. This string needs to include {id} in it, where the card id will be 'injected' automatically into it. As an example hrefPath="/events/{id}"

The basic structure of the card consists of an optional thumbnail, a body and an optional action section which can be customized through config object.

Match Card relies on MCLS Events status and will display different visual behaviours based on the current status of the event. For example, live events show scores while upcoming events display event start time, and the default styles and label for the card action buttons is different for each event status. This can be overriden through config.

import { MatchCard } from "@mycujoo/mcls-components";

const dataPaths = {
  homeTeamLogo: 'metadata.home_team.logo',
  homeTeamName: 'metadata.home_team.name',
  homeTeamShortCode: 'metadata.home_team.abbreviation',
  homeTeamScore: 'metadata.home_team.score',
  awayTeamLogo: 'metadata.away_team.logo',
  awayTeamName: 'metadata.away_team.name',
  awayTeamShortCode: 'metadata.away_team.abbreviation',
  awayTeamScore: 'metadata.away_team.score',
  eventVenue: 'location.physical.venue',
  startTime: 'start_time',
  status: 'status',
  thumbnailUrl: 'thumbnail_url',
  viewers: 'viewers',
  leagueName: 'metadata.league_name',
  id: "id"
}

<MatchCard
  dataPaths={dataPaths}
  onClick={handleCardClick}
  config={{
    size: 'm',
    borderRadius: '16px',
    thumbnail: {
      icon: true,
      viewers: true,
    },
    action: {
      buttonConfig: {
        position: 'left',
        text: 'Custom text',
        borderRadius: '4px',
        type: 'outlined',
      },
    },
    showSeparator: true,
    primaryColor: '#ddd000',
    secondaryColor: '#000ddd',
    showTag: true,
  }}
/>
Simple Card

This card is intended to be used for any event or data where only a title, a subtitle or description and aditional data like time is needed to be displayed.

SimpleCard receives data object directly from the parent slider, grid or column.

It requires dataPaths object which maps the path from the event data object to the different fields that are displayed (Title, subtitle, thumbnail, id, etc). Clicking on the card may be handled through a function passed as onClick or as a <a> HTML element. href value for the card is provided through hrefBasePath. This string needs to include {id} in it, where the card id will be 'injected' automatically into it. As an example hrefPath="/events/{id}"

import { SimpleCard } from "@mycujoo/mcls-components";

const dataPaths = {
  title: 'title',
  titleRight: 'metadata.highlight_time',
  thumbnailUrl: 'thumbnail_url',
  subtitle: 'description',
}

<SimpleCard
  dataPaths={dataPaths}
  onClick={handleCardClick}
  config={{
    size: 'm',
    thumbnail: { viewers: false, borderRadius: 6, height: 150 },
    textColor: '#fff',
    bgColor: 'transparent',
    bodyPadding: '20px 0',
    title: {
      fontSize: 20,
      fontWeight: 500,
    },
  }}
/>
Match Line Card

This Match Line is intended to be used as a card in a column for listing Match-type events where there are two teams and the match start time needs to be displayed.

MatchLine receives data object directly from the parent column.

It requires to be passed at least dataPaths object which maps the path from the event data object to the different fields that are displayed (team names, scores, logos, event start time, id, etc). Clicking on the card may be handled through a function passed as onClick or as a <a> HTML element. href value for the card is provided through hrefBasePath. This string needs to include {id} in it, where the card id will be 'injected' automatically into it. As an example hrefPath="/events/{id}"

import { MatchLine } from "@mycujoo/mcls-components";

const dataPaths = {
  homeTeamLogo: 'metadata.home_team.logo',
  homeTeamName: 'metadata.home_team.name',
  awayTeamLogo: 'metadata.away_team.logo',
  awayTeamName: 'metadata.away_team.name',
  textLeft: 'location.physical.venue',
  startTime: 'start_time',
  textRight: 'start_time',
}

<MatchLine
  dataPaths={dataPaths}
  onClick={handleCardClick}
  config={{
    bgColor: 'white',
    borderRadius: 4,
    height: 30,
    padding: '5px 25px',
  }}
/>

Player component

To use the react player import Player from the library and pass at least a valid MCLS eventId and you MCLS publicKey

Import
import { Player } from '@mycujoo/mcls-components'
Usage
<Player
  eventId= 'EVENT_ID'
  publicKey= 'PUBLIC_KEY'
  identityToken=''
  primaryColor="#FFF"
  secondaryColor="#000"
  autoplay
  debug
  showInfoButton
  showLiveViewers
  showSeekbar
  showFullscreen
  showBackForwardButtons
  showQualitySelector
  showVolume
  showTimers
  showChromecast
  showPictureInPicture
  enableAnnotations
  analyticsType= 'youbora'
  lang= 'en'
  analyticsAccount=''
  analyticsUserId=''
  defaultVolume={0}
  startPosition={0}
  seekTo={0}
  totalViewers={0}
  customPlaylistUrl=''
  adUnit=''
  adCustParams = 'age_category=u19&id_channel=6486&logged_in=1'
  className=''
  analyticsCustomParams= {
    customParam1: 'test p1',
    customParam3: 'test p3',
    customParam4: 'test p4',
    customParam5: 'test p5',
    customParam6: 'test p6',
    customParam7: 'test p7',
  }
  globalStyle={globalStyle}
  onTimeUpdate={action('onTimeUpdate')}
  onTimerUpdate={action('onTimerUpdate')}
  onGetTitle={action('onGetTitle')}
  onGetEvent={action('onGetEvent')}
  onVideoPlay={action('onVideoPlay')}
  onVideoPause={action('onVideoPause')}
  onVideoEnd={action('onVideoEnd')}
  onSeeking={action('onVideoSeeking')}
  onSeeked={action('onVideoSeeking')}
  onWaiting={action('onWaiting')}
  onMediaControlChange={action('onMediaControlChange')}
  onFullscreenChange={action('onFullscreenChange')}
  onPlayerViewChange={action('onPlayerViewChange')}
  onGetMetadata={action('onGetMetadata')}
  onPlayerInit={action('onPlayerInit')}
  onAdsBreakStart={action('onAdsBreakStart')}
  onAdStart={action('onAdStart')}
  onAdSkip={action('onAdSkip')}
  onAdComplete={action('onAdComplete')}
  onAdsBreakComplete={action('onAdsBreakComplete')}
  onAdsManager={action('onAdsManager')}
  onQualityChange={action('onQualityChange')}
  >
    <div>Injected content</div>
  </Player>
Required props
NameTypeDescription
eventIdstringMCLS event id
publicKeystringMCLS account public key
Optional props
NameTypeDefaultDescription
childrennodeundefinedThe children of the Player component will be injected in the player and should be visible when going to fullscreen etc.
autoplaybooleanfalseIndicates if video should autoplay
debugbooleanfalseIndicates if debug messages should be shown
showInfoButtonbooleanfalseControls visibility of info button
showLiveViewersbooleanfalseControls visibility of info live simultaneous viewers
showSeekbarbooleantrueControls visibility of seekbar
showFullscreenbooleantrueControls visibility of fullscreen button
showBackForwardButtonsbooleanfalseControls visibility of +10, -10s buttons
showQualitySelectorbooleantrueControls visibility of quality selector
showVolumebooleantrueControls visibility of volume selector
showTimersbooleantrueControls visibility of timers
showChromecastbooleanfalseEnables or disables the chromecast feature
showPictureInPicturebooleantrueControls visibility of picture in picture button
enableAnnotationsbooleantrueEnables or disables the annotations feature
analyticsTypeyoubora,muxtrueSpecifies which type of analytics to use
analyticsAccountstringundefinedAnalytics account id
analyticsUserIdstringundefinedUnique user id for analytics;
analyticsCustomParams{ customParam1: string, customParam3: string, customParam4: string -> customParam12: string, customParam13: string }undefinedFlat object with customParamers starting from 1 to 12 (2 is reserved)
startPositionnumber0Indicates starting playback possition
seekTonumber0Indicates position to seek to
totalViewersnumber0Number of viewers to show on live events
customPlaylistUrlstringundefinedPlaylist to play instead of event source
infoReactElementdefaultInfoCustom info overlay
preloaderReactElementundefinedCustom preloader
geoblockedScreenReactElementdefaultTextScreenCustom geoblocked screen
preEventScreenReactElementdefaultTextScreenCustom scheduled event screen
authorizationScreenReactElementdefaultTextScreenCustom authorization / payment screen
streamErrorScreenReactElementdefaultTextScreenCustom error screen
lang'de', 'en', 'es', 'fr', 'id', 'it', 'ja', 'ms', 'pt', 'ru', 'th', 'zh', 'ar', 'ko'enLanguage for the default text screen messages.
globalStyleObject{}Style object (@emotion global style object)
onTimerUpdate(currentTime: number, totalTime: number) => voidundefinedFunction called whenever video display timers update
onTimeUpdate(videoTime: number) => voidundefinedFunction called on video player timeupdate event
onVideoPlay() => voidundefinedFunction called on video player play event
onFirstPlay() => voidundefinedFunction called on video player first play event
onVideoPause() => voidundefinedFunction called on video player pause event
onSeeking() => voidundefinedFunction called on video player seeking event
onSeeked() => voidundefinedFunction called on video player seeked event
onWaiting() => voidundefinedFunction called on video player waiting event
onVideoEnd() => voidundefinedFunction called on video player ended event
onGetTitle(title: string) => voidundefinedFunction called when event title is fetched
onGetEvent(event: EventInformation) => voidundefinedFunction called when event information is fetched
onGetMetadata(metadata: unknown) => voidundefinedFunction called when event metadata is fetched
onMediaControlChange(isOpen: boolean) => voidundefinedFunction called when media control visibility changes. This is triggered on an internal player event when user causes the control bar to show up.
onFullscreenChange(isFullscreen: boolean) => voidundefinedFunction called when full screen value changes
onVideoTypeChange(videoType: 'vod' | 'live') => voidundefinedFunction called when video type changes
onPlayerViewChange(eventViews: PlayerView) => voidundefinedFunction called when player shows a different internal screen
onPlayerInit(playerInstance: PlayerInstance) => voidundefinedFunction called after internal video player is created
onAdsManager(adsManager: GoogleImaAdsManager) => voidundefinedFunction called after google ima manager is created; GoogleImaAdsManager is the IMA SDK ads manager
onAdsBreakStart() => voidundefinedFunction called after ima ad break starts
onAdStart(ad: GoogleImaAd | null) => voidundefinedFunction called after ima ad starts playing; GoogleImaAd is the IMA SDK ad
onAdComplete() => voidundefinedFunction called after ima ad finished playing
onAdsBreakComplete() => voidundefinedFunction called after ima ad break is completed
onQualityChange(newValue: { bitrate: number, height: number, width: number}) => voidundefinedFunction called when video quality changes; This also triggers when quality changes internally
0.1.8

9 months ago

0.1.7

11 months ago

0.1.6

12 months ago

0.1.1-rc.1

1 year ago

0.1.1-rc.0

1 year ago

0.0.68-rc.0

1 year ago

0.1.0-rc.0

1 year ago

0.1.4-rc5

1 year ago

0.1.4-rc2

1 year ago

0.1.4-rc1

1 year ago

0.1.4-rc4

1 year ago

0.1.4-rc3

1 year ago

0.0.69-rc.4

1 year ago

0.0.69-rc.3

1 year ago

0.0.69-rc.0

1 year ago

0.0.69-rc.2

1 year ago

0.0.69-rc.1

1 year ago

0.0.67-rc.1

1 year ago

0.0.67-rc.0

1 year ago

0.1.6-rc.0

1 year ago

0.1.6-rc.2

1 year ago

0.1.6-rc.1

1 year ago

0.0.66

1 year ago

0.0.67

1 year ago

0.0.68

1 year ago

0.1.0

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.4

1 year ago

0.1.3

1 year ago

0.1.5

1 year ago

0.0.65-rc.0

1 year ago

0.0.0-rc.3

1 year ago

0.0.0-rc.2

1 year ago

0.0.0-rc.1

1 year ago

0.0.0-rc.0

1 year ago

0.0.64

1 year ago

0.0.65

1 year ago

1.0.0-rc.5

1 year ago

1.0.0-rc.6

1 year ago

1.0.0-rc.3

1 year ago

1.0.0-rc.4

1 year ago

1.0.0-rc.1

1 year ago

1.0.0-rc.2

1 year ago

1.0.0-rc.0

1 year ago

0.0.63

1 year ago

0.0.64-rc.1

1 year ago

0.0.64-rc.0

1 year ago

0.0.62-rc.0

1 year ago

0.0.59-rc.1

1 year ago

0.0.59-rc.0

1 year ago

0.0.61-rc.0

1 year ago

0.0.62

1 year ago

0.0.60

1 year ago

0.0.61

1 year ago

0.0.59

1 year ago

0.0.60-rc.0

1 year ago

0.0.60-rc.1

1 year ago

0.0.58-rc.0

2 years ago

0.0.58-rc.1

2 years ago

0.0.58-rc.2

2 years ago

0.0.58-rc.3

2 years ago

0.0.58-rc.4

2 years ago

0.0.58-rc.5

2 years ago

0.0.57-rc.3

2 years ago

0.0.57-rc.2

2 years ago

0.0.57-rc.4

2 years ago

0.0.57-rc.1

2 years ago

0.0.57-rc.0

2 years ago

0.0.51-rc.2

2 years ago

0.0.51-rc.3

2 years ago

0.0.51-rc.0

2 years ago

0.0.51-rc.1

2 years ago

0.0.51-rc.6

2 years ago

0.0.51-rc.7

2 years ago

0.0.51-rc.4

2 years ago

0.0.51-rc.5

2 years ago

0.0.51-rc.8

2 years ago

0.0.51-rc.9

2 years ago

0.0.55-rc.0

2 years ago

0.0.56-rc.0

2 years ago

0.0.51

2 years ago

0.0.52

2 years ago

0.0.53

2 years ago

0.0.54

2 years ago

0.0.55

2 years ago

0.0.56

2 years ago

0.0.57

2 years ago

0.0.58

2 years ago

0.0.50

2 years ago

0.0.48

2 years ago

0.0.49

2 years ago

0.0.51-rc.12

2 years ago

0.0.51-rc.11

2 years ago

0.0.51-rc.10

2 years ago

0.0.54-rc.1

2 years ago

0.0.43-rc.5

2 years ago

0.0.43-rc.6

2 years ago

0.0.43-rc.3

2 years ago

0.0.43-rc.4

2 years ago

0.0.43

2 years ago

0.0.44

2 years ago

0.0.45

2 years ago

0.0.46

2 years ago

0.0.47

2 years ago

0.0.44-rc.0

2 years ago

0.0.46-rc.0

2 years ago

0.0.46-rc.1

2 years ago

0.0.47-rc.0

2 years ago

0.0.43-rc.2

2 years ago

0.0.43-rc.0

2 years ago

0.0.42-rc.4

2 years ago

0.0.42-rc.3

2 years ago

0.0.42-rc.2

2 years ago

0.0.42-rc.1

2 years ago

0.0.42-rc.0

2 years ago

0.0.41-rc.9

2 years ago

0.0.40

2 years ago

0.0.41

2 years ago

0.0.42

2 years ago

0.0.40-rc.98

2 years ago

0.0.40-rc.99

2 years ago

0.0.41-rc.0

2 years ago

0.0.41-rc.1

2 years ago

0.0.41-rc.2

2 years ago

0.0.41-rc.3

2 years ago

0.0.41-rc.4

2 years ago

0.0.41-rc.5

2 years ago

0.0.41-rc.6

2 years ago

0.0.41-rc.7

2 years ago

0.0.41-rc.8

2 years ago

0.0.40-rc.5

2 years ago

0.0.40-rc.7

2 years ago

0.0.40-rc.6

2 years ago

0.0.40-rc.1

2 years ago

0.0.40-rc.3

2 years ago

0.0.40-rc.2

2 years ago

0.0.40-rc.9

2 years ago

0.0.40-rc.8

2 years ago

0.0.40-rc.10

2 years ago

0.0.40-rc.12

2 years ago

0.0.40-rc.11

2 years ago

0.0.40-rc.14

2 years ago

0.0.40-rc.13

2 years ago

0.0.40-rc.15

2 years ago

0.0.37

2 years ago

0.0.38

2 years ago

0.0.38-rc.0

2 years ago

0.0.38-rc.1

2 years ago

0.0.38-rc.2

2 years ago

0.0.34

2 years ago

0.0.35

2 years ago

0.0.36

2 years ago

0.0.35-rc.0

2 years ago

0.0.35-rc.2

2 years ago

0.0.34-rc.0

2 years ago

0.0.34-rc.1

2 years ago

0.0.34-rc.2

2 years ago

0.0.34-rc.3

2 years ago

0.0.34-rc.4

2 years ago

0.0.33-rc.4

2 years ago

0.0.33-rc.5

2 years ago

0.0.33-rc.0

2 years ago

0.0.33-rc.1

2 years ago

0.0.33-rc.2

2 years ago

0.0.33-rc.3

2 years ago

0.0.30-rc.0

2 years ago

0.0.27-rc.0

2 years ago

0.0.28-rc2

2 years ago

0.0.28-rc3

2 years ago

0.0.28-rc1

2 years ago

0.0.24-rc.8

2 years ago

0.0.24-rc.6

2 years ago

0.0.24-rc.7

2 years ago

0.0.24-rc.4

2 years ago

0.0.24-rc.5

2 years ago

0.0.27-rc.5

2 years ago

0.0.24-rc.3

2 years ago

0.0.27-rc.4

2 years ago

0.0.27-rc.3

2 years ago

0.0.27-rc.2

2 years ago

0.0.27-rc.1

2 years ago

0.0.26-rc.0

2 years ago

0.0.26-rc.1

2 years ago

0.0.26-rc.2

2 years ago

0.0.25-rc.0

2 years ago

0.0.25-rc.2

2 years ago

0.0.25-rc.1

2 years ago

0.0.25-rc.4

2 years ago

0.0.25-rc.3

2 years ago

0.0.28-rc.6

2 years ago

0.0.30

2 years ago

0.0.31

2 years ago

0.0.32

2 years ago

0.0.33

2 years ago

0.0.31-rc.0

2 years ago

0.0.26

2 years ago

0.0.27

2 years ago

0.0.28

2 years ago

0.0.29

2 years ago

0.0.24

2 years ago

0.0.25

2 years ago

0.0.29-rc.1

2 years ago

0.0.29-rc.0

2 years ago

0.0.23-rc.0

2 years ago

0.0.23-rc.2

2 years ago

0.0.23-rc.1

2 years ago

0.0.24-rc.2

2 years ago

0.0.24-rc.0

2 years ago

0.0.24-rc.1

2 years ago

0.0.22-rc.3

2 years ago

0.0.22-rc.2

2 years ago

0.0.22-rc.1

2 years ago

0.0.22-rc.0

2 years ago

0.0.22-rc.9

2 years ago

0.0.22-rc.8

2 years ago

0.0.22-rc.7

2 years ago

0.0.22-rc.6

2 years ago

0.0.22-rc.5

2 years ago

0.0.22-rc.4

2 years ago

0.0.19-rc.0

2 years ago

0.0.20

2 years ago

0.0.21

2 years ago

0.0.22

2 years ago

0.0.23

2 years ago

0.0.18-rc.0

2 years ago

0.0.18-rc.1

2 years ago

0.0.16

2 years ago

0.0.17

2 years ago

0.0.16-rc.1

2 years ago

0.0.18

2 years ago

0.0.16-rc.2

2 years ago

0.0.19

2 years ago

0.0.16-rc.0

2 years ago

0.0.20-rc.1

2 years ago

0.0.20-rc.0

2 years ago

0.0.20-rc.3

2 years ago

0.0.20-rc.2

2 years ago

0.0.20-rc.5

2 years ago

0.0.17-rc.1

2 years ago

0.0.20-rc.4

2 years ago

0.0.17-rc.0

2 years ago

0.0.15

2 years ago

0.0.15-rc.4

2 years ago

0.0.15-rc.2

2 years ago

0.0.15-rc.1

2 years ago

0.0.15-rc.0

2 years ago

0.0.14

2 years ago

0.0.14-rc.6

2 years ago

0.0.14-rc.5

2 years ago

0.0.14-rc.4

2 years ago

0.0.14-rc.3

2 years ago

0.0.14-rc.1

2 years ago

0.0.13

2 years ago

0.0.13-rc.2

2 years ago

0.0.13-rc.1

2 years ago

0.0.12

2 years ago

0.0.12-rc.0

2 years ago

0.0.1-2.rc-0

2 years ago

0.0.11

2 years ago

0.0.11-rc.2

2 years ago

0.0.11-rc.1

2 years ago

0.0.11-rc.0

2 years ago

0.0.10

2 years ago

0.0.10-rc.1

2 years ago

0.0.10-rc.0

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7-rc.17

2 years ago

0.0.7-rc.16

2 years ago

0.0.7-rc.15

2 years ago

0.0.7-rc.14

2 years ago

0.0.7-rc.13

2 years ago

0.0.7-rc.12

2 years ago

0.0.7-rc.11

2 years ago

0.0.7-rc.10

2 years ago

0.0.7-rc.0

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.6-rc.1

2 years ago

0.0.6-rc.0

2 years ago

0.0.5

2 years ago

0.0.5-rc.5

2 years ago

0.0.5-rc.4

2 years ago

0.0.5-rc.3

2 years ago

0.0.5-rc.2

2 years ago

0.0.5-rc.1

2 years ago

0.0.5-rc.0

2 years ago

0.0.4

2 years ago

0.0.4-rc.8

2 years ago

0.0.4-rc.6

2 years ago

0.0.4-rc.5

2 years ago

0.0.4-rc.4

2 years ago

0.0.4-rc.3

2 years ago

0.0.4-rc.2

2 years ago

0.0.4-rc.1

2 years ago

0.0.3

2 years ago

0.0.3-rc.8

2 years ago

0.0.3-rc.7

2 years ago

0.0.3-rc.6

2 years ago

0.0.3-rc.5

2 years ago

0.0.3-rc.4

2 years ago

0.0.3-rc.3

2 years ago

0.0.3-rc.2

2 years ago

0.0.3-rc.1

2 years ago

0.0.2

2 years ago

0.0.1-rc16

2 years ago

0.0.1-rc15

2 years ago

0.0.1-rc14

2 years ago

0.0.1-rc13

2 years ago

0.0.1-rc12

2 years ago

0.0.1-rc11

2 years ago

0.0.1-rc10

2 years ago

0.0.1-rc9

2 years ago

0.0.1-rc8

2 years ago

0.0.1-rc7

2 years ago

0.0.1-rc6

2 years ago

0.0.1-rc4

2 years ago

0.0.1-rc3

2 years ago

0.0.1-rc2

2 years ago

0.0.1-rc1

2 years ago

0.0.1

2 years ago