<template>
  <div
    class="d-flex flex-column mb-6 bg-surface-variant"
  >
    <v-sheet class="ma-2 pa-2">Flex item 1</v-sheet>
    <v-sheet class="ma-2 pa-2">Flex item 2</v-sheet>
    <v-sheet class="ma-2 pa-2">Flex item 3</v-sheet>
  </div>
  <div
    class="d-flex flex-column-reverse mb-6 bg-surface-variant"
  >
    <v-sheet class="ma-2 pa-2">Flex item 1</v-sheet>
    <v-sheet class="ma-2 pa-2">Flex item 2</v-sheet>
    <v-sheet class="ma-2 pa-2">Flex item 3</v-sheet>
  </div>
</template>


keep keep keep replace keep keep keep keep keep

<template>
  <v-sheet
    v-if="sponsors.length"
    id="home-sponsors"
    class="mx-auto pa-3"
    color="transparent"
    max-width="700"
  >
    <v-responsive
      class="mb-12"
      min-height="500"
    >
      <v-row
        dense
        justify="center"
      >
        <v-col
          v-for="sponsor in sponsors"
          :key="sponsor.slug"
          :md="sponsor.metadata.tier > 1 ? 3 : 5"
          class="d-flex align-center justify-center"
          cols="auto"
        >
          <sponsor-card
            :comfortable="Number(sponsor.metadata.tier) === 2"
            :compact="Number(sponsor.metadata.tier) > 2"
            :sponsor="sponsor"
            v-bind="$attrs"
          />
        </v-col>
      </v-row>
    </v-responsive>

    <sponsor-link size="large" />
  </v-sheet>
</template>

<script lang="ts">
  // Utilities
  import { computed, defineComponent, onBeforeMount } from 'vue'
  import { useSponsorsStore } from '../../store/sponsors'

  import SponsorCard from '@/components/sponsor/Card.vue'
  import SponsorLink from '@/components/sponsor/Link.vue'

  export default defineComponent({
    name: 'Sponsors',

    components: {
      SponsorCard,
      SponsorLink,
    },

    setup () {
      const sponsorStore = useSponsorsStore()

      onBeforeMount(async () => sponsorStore.load())

      const sponsors = computed(() => {
        return Object.values(sponsorStore.byTier)
          .reduce((tiers, tier) => {
            for (const sponsor of tier) {
              if (Number(sponsor.metadata.tier) < 0) continue

              tiers.push(sponsor)
            }

            return tiers
          }, [] as any[])
      })

      return {
        sponsors,
      }
    },

  })
</script>


keep keep keep keep add keep keep keep keep

@use 'sass:map'
@use 'sass:selector'
@use '../../styles/settings'
@use '../../styles/tools'
@use './variables' as *
@use '../VInput/variables' as *

/* region INPUT */
.v-field
  display: grid
  grid-template-areas: "prepend-inner field clear append-inner"
  grid-template-columns: min-content minmax(0, 1fr) min-content min-content
  font-size: $field-font-size
  letter-spacing: $field-letter-spacing
  max-width: $field-max-width
  border-radius: $field-border-radius
  contain: layout
  flex: 1 0
  grid-area: control
  position: relative

  &--disabled
    opacity: var(--v-disabled-opacity)
    pointer-events: none

  --v-field-padding-start: #{$field-control-padding-start}
  --v-field-padding-end: #{$field-control-padding-end}
  --v-field-padding-top: #{$field-control-padding-top}
  --v-field-padding-bottom: #{$field-control-padding-bottom}

/* endregion */
/* region MODIFIERS */
.v-field
  &--prepended
    padding-inline-start: $field-control-affixed-padding

  &--appended
    padding-inline-end: $field-control-affixed-padding

  &--variant-solo
    background: $field-control-solo-background
    border-color: transparent
    color: $field-control-solo-color

    @include tools.elevation($field-control-solo-elevation)

  &--variant-filled
    border-bottom-left-radius: 0
    border-bottom-right-radius: 0

  &--variant-plain,
  &--variant-underlined
    border-radius: 0
    padding: 0
    --v-field-padding-start: 0px
    --v-field-padding-end: 0px
    --v-field-padding-top: 6px
    --v-field-padding-bottom: 2px

  &--variant-outlined,
  &--single-line
    --v-field-padding-top: 0px
    $root: &

    @at-root
      @include tools.density('v-input', $input-density) using ($modifier)
        @at-root #{selector.nest(&, $root)}
          --v-field-padding-bottom: #{16px + $modifier * .5}

  &--variant-solo,
  &--variant-filled
    $root: &

    @at-root
      @include tools.density('v-input', $input-density) using ($modifier)
        @at-root #{selector.nest(&, $root)}
          --v-input-control-height: #{$field-control-height + $modifier}
          --v-field-padding-bottom: #{$field-control-padding-bottom + $modifier * .5}

  &--variant-plain,
  &--variant-underlined
    $root: &

    @at-root
      @include tools.density('v-input', $input-density) using ($modifier)
        @at-root #{selector.nest(&, $root)}
          --v-input-control-height: #{$field-control-underlined-height + $modifier}

  // These are separate so they can override the default variant styles
  &--prepended
    --v-field-padding-start: #{$field-control-affixed-inner-padding}

  &--appended
    --v-field-padding-end: #{$field-control-affixed-inner-padding}

/* endregion */
/* region ELEMENTS */
.v-field__input
  color: inherit
  display: flex
  flex-wrap: wrap
  letter-spacing: $field-letter-spacing
  opacity: $field-input-opacity
  min-height: var(--v-input-control-height, $input-control-height)
  padding-inline-start: var(--v-field-padding-start)
  padding-inline-end: var(--v-field-padding-end)
  padding-top: calc(var(--v-field-padding-top, $field-control-padding-top) + var(--v-input-padding-top, 0))
  padding-bottom: var(--v-field-padding-bottom, $field-control-padding-bottom)
  width: 100%

  input
    letter-spacing: inherit

  @at-root
    & input::placeholder,
    input#{&}::placeholder,
    textarea#{&}::placeholder
      color: currentColor
      opacity: var(--v-disabled-opacity)

  &:focus,
  &:active
    outline: none

  // Remove Firefox red outline
  &:invalid
    box-shadow: none

.v-field__field
  flex: 1 0
  grid-area: field
  position: relative
  align-items: flex-start
  display: flex

/* endregion */
/* region AFFIXES */
.v-field__prepend-inner
  grid-area: prepend-inner
  padding-inline-end: var(--v-field-padding-after)

.v-field__clearable
  grid-area: clear

.v-field__append-inner
  grid-area: append-inner
  padding-inline-start: var(--v-field-padding-after)

.v-field__prepend-inner,
.v-field__append-inner,
.v-field__clearable
  align-items: flex-start
  display: flex
  padding-top: var(--v-input-padding-top, $field-control-padding-top)

.v-field__prepend-inner,
.v-field__append-inner
  .v-field--focused &
    opacity: 1

.v-field__prepend-inner,
.v-field__append-inner,
.v-field__clearable
  > .v-icon
    opacity: var(--v-medium-emphasis-opacity)

  .v-field--disabled &,
  .v-field--error &
    > .v-icon
      opacity: 1

  .v-field--error:not(.v-field--disabled) &
    > .v-icon
      color: rgb(var(--v-theme-error))

.v-field__clearable
  cursor: pointer
  opacity: 0
  margin-inline-start: $field-clearable-margin
  margin-inline-end: $field-clearable-margin
  transition: $field-transition-timing
  transition-property: opacity, transform, width

  .v-field--focused &,
  .v-field--persistent-clear &
    opacity: 1

  @media (hover: hover)
    .v-field:hover &
      opacity: 1

/* endregion */
/* region LABEL */
.v-label.v-field-label
  contain: layout paint
  margin-inline-start: var(--v-field-padding-start)
  margin-inline-end: var(--v-field-padding-end)
  max-width: calc(100% - var(--v-field-padding-start) - var(--v-field-padding-end))
  pointer-events: none
  position: absolute
  top: var(--v-input-padding-top, $field-control-padding-top)
  transform-origin: left center
  transition: $field-transition-timing
  transition-property: opacity, transform

  .v-field--active &
    visibility: hidden

  .v-field--disabled &,
  .v-field--focused &,
  .v-field--error &
    opacity: 1

  .v-field--error:not(.v-field--disabled) &
    color: rgb(var(--v-theme-error))

  &--floating
    --v-field-label-scale: #{$field-label-floating-scale}em
    font-size: var(--v-field-label-scale)
    visibility: hidden
    max-width: 100%

    .v-field.v-field--active &
      visibility: visible

    .v-field--variant-solo &,
    .v-field--variant-filled &
      $root: &

      @at-root
        @include tools.density('v-input', $input-density) using ($modifier)
          @at-root #{selector.nest(&, $root)}
            top: 7px + $modifier * .25

    .v-field--variant-plain &,
    .v-field--variant-underlined &
      transform: translateY(-16px)
      margin: 0

    .v-field--variant-outlined &
      transform: translateY(-50%)
      transform-origin: center
      position: static
      margin: 0 4px

/* endregion */
/* region OUTLINE */
.v-field__outline
  --v-field-border-width: #{$field-border-width}
  --v-field-border-opacity: #{$field-outline-opacity}
  align-items: stretch
  contain: layout
  display: flex
  height: 100%
  left: 0
  pointer-events: none
  position: absolute
  right: 0
  width: 100%

  @media (hover: hover)
    .v-field:hover &
      --v-field-border-opacity: var(--v-high-emphasis-opacity)

  .v-field--error:not(.v-field--disabled) &
    color: rgb(var(--v-theme-error))

  .v-field.v-field--focused &,
  .v-input.v-input--error &
    --v-field-border-opacity: 1

  .v-field--variant-outlined.v-field--focused &
    --v-field-border-width: #{$field-focused-border-width}

  .v-field--variant-filled &,
  .v-field--variant-underlined &
    &::before
      border-style: solid
      border-width: 0 0 var(--v-field-border-width)
      opacity: var(--v-field-border-opacity)
      transition: opacity $field-subtle-transition-timing
      @include tools.absolute(true)

  .v-field--variant-filled &,
  .v-field--variant-underlined &
    &::after
      border-color: currentColor
      border-style: solid
      border-width: 0 0 $field-focused-border-width
      transform: scaleX(0)
      transition: transform $field-transition-timing
      @include tools.absolute(true)

      @at-root #{selector.append('.v-field--focused', &)}
        transform: scaleX(1)

  .v-field--variant-outlined &
    border-radius: inherit

    &__start,
    &__notch::before,
    &__notch::after,
    &__end
      border: 0 solid currentColor
      opacity: var(--v-field-border-opacity)
      transition: opacity $field-subtle-transition-timing

    &__start
      flex: 0 0 $field-control-affixed-padding
      border-top-width: var(--v-field-border-width)
      border-bottom-width: var(--v-field-border-width)
      border-inline-start-width: var(--v-field-border-width)

      @include tools.ltr()
        border-radius: $field-border-radius 0 0 $field-border-radius

      @include tools.rtl()
        border-radius: 0 $field-border-radius $field-border-radius 0

    &__notch
      flex: none
      position: relative
      border-width: 0 0 var(--v-field-border-width)

      &::before,
      &::after
        opacity: var(--v-field-border-opacity)
        transition: opacity $field-subtle-transition-timing

        @include tools.absolute(true)

      &::before
        border-width: var(--v-field-border-width) 0 0

      &::after
        bottom: 0
        border-width: 0 0 var(--v-field-border-width)

      @at-root #{selector.append('.v-field--active', &)}
        &::before
          opacity: 0

    &__end
      flex: 1
      border-top-width: var(--v-field-border-width)
      border-bottom-width: var(--v-field-border-width)
      border-inline-end-width: var(--v-field-border-width)

      @include tools.ltr()
        border-radius: 0 $field-border-radius $field-border-radius 0

      @include tools.rtl()
        border-radius: $field-border-radius 0 0 $field-border-radius
/* endregion */
/* region LOADER */
.v-field__loader
  bottom: 0
  left: 0
  position: absolute
  right: 0
  width: 100%

/* endregion */
/* region OVERLAY */
.v-field--variant-filled
  .v-field__overlay
    background-color: currentColor
    border-radius: inherit
    opacity: $field-overlay-filled-opacity
    pointer-events: none
    transition: opacity $field-subtle-transition-timing
    @include tools.absolute()

  &.v-field--has-background .v-field__overlay
    opacity: 0

  @media (hover: hover)
    &:hover .v-field__overlay
      opacity: calc(#{$field-overlay-filled-opacity + map.get(settings.$states, 'hover')} * var(--v-theme-overlay-multiplier))

  &.v-field--focused .v-field__overlay
    opacity: calc(#{$field-overlay-filled-opacity + map.get(settings.$states, 'focus')} * var(--v-theme-overlay-multiplier))

/* endregion */
/* region MODIFIERS */
.v-field--reverse
  .v-field__input
    @include tools.ltr()
      text-align: right

    @include tools.rtl()
      text-align: left

.v-field--variant-filled,
.v-field--variant-underlined
  .v-input--disabled &
    .v-field__outline::before
      border-image: repeating-linear-gradient(to right, $field-disabled-color 0px, $field-disabled-color 2px, transparent 2px, transparent 4px) 1 repeat

.v-field--loading
  .v-field__outline::after,
  .v-field__outline::before
    opacity: 0

/* endregion */


.v-virtual-scroll
  display: block
  flex: 1 1 auto
  height: 100%
  max-width: 100%
  overflow: auto
  position: relative

  &__container
    display: block

  &__item
    left: 0
    position: absolute
    right: 0


<template>
  <v-sheet
    class="d-flex align-content-space-between flex-wrap bg-surface-variant"
    min-height="200"
  >
    <v-sheet
      v-for="n in 20"
      :key="n"
      class="ma-2 pa-2"
    >
      Flex item
    </v-sheet>
  </v-sheet>
</template>


module.exports = {
  'v-tab': {
    slots: [
      {
        name: 'default',
        props: undefined,
      },
    ],
    events: [
      {
        name: 'change',
        value: 'void',
      },
      {
        name: 'click',
        value: 'ClickEvent',
      },
      {
        name: 'keydown',
        value: 'KeyboardEvent',
      },
    ],
  },
}


keep keep keep keep keep replace replace replace replace keep keep keep keep


<template>
  <div class="text-center">
    <v-progress-circular
      :size="50"
      color="primary"
      indeterminate
    ></v-progress-circular>

    <v-progress-circular
      :width="3"
      color="red"
      indeterminate
    ></v-progress-circular>

    <v-progress-circular
      :size="70"
      :width="7"
      color="purple"
      indeterminate
    ></v-progress-circular>

    <v-progress-circular
      :width="3"
      color="green"
      indeterminate
    ></v-progress-circular>

    <v-progress-circular
      :size="50"
      color="amber"
      indeterminate
    ></v-progress-circular>
  </div>
</template>

<style scoped>
.v-progress-circular {
  margin: 1rem;
}
</style>


// @ts-nocheck
/* eslint-disable */

// import VDataFooter from '../VDataFooter'
// import { Lang } from '../../../services/lang'
import {
  mount,
  MountOptions,
  Wrapper,
} from '@vue/test-utils'
// import Vue from 'vue'
// import { preset } from '../../../presets/default'

// Vue.prototype.$vuetify = {
//   icons: {
//     values: {
//       prev: 'mdi-chevron-left',
//       next: 'mdi-chevron-right',
//       dropdown: 'mdi-menu-down',
//       first: 'mdi-page-first',
//       last: 'mdi-page-last',
//     },
//   },
// }

describe.skip('VDataFooter.ts', () => {
  type Instance = InstanceType<typeof VDataFooter>
  let mountFunction: (options?: MountOptions<Instance>) => Wrapper<Instance>
  beforeEach(() => {
    document.body.setAttribute('data-app', '')

    mountFunction = (options?: MountOptions<Instance>) => {
      return mount(VDataFooter, {
        // https://github.com/vuejs/vue-test-utils/issues/1130
        sync: false,
        mocks: {
          $vuetify: {
            lang: new Lang(preset),
            theme: {
              dark: false,
            },
          },
        },
        ...options,
      })
    }
  })

  it('should render with custom itemsPerPage', () => {
    const wrapper = mountFunction({
      propsData: {
        itemsPerPageOptions: [50, 100],
        options: {
          page: 4,
          itemsPerPage: 100,
        },
        pagination: {
          page: 4,
          itemsPerPage: 10,
          pageStart: 1,
          pageStop: 10,
          pageCount: 10,
          itemsLength: 100,
        },
      },
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  it('should render in RTL mode', () => {
    const wrapper = mountFunction({
      propsData: {
        options: {
          page: 4,
          itemsPerPage: 10,
        },
        pagination: {
          page: 4,
          itemsPerPage: 10,
          pageStart: 1,
          pageStop: 10,
          pageCount: 10,
          itemsLength: 100,
        },
        showFirstLastPage: true,
      },
      mocks: {
        $vuetify: {
          rtl: true,
          lang: new Lang(preset),
          theme: {
            dark: false,
          },
        },
      },
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  it('should render first & last icons with showFirstLastPage', () => {
    const wrapper = mountFunction({
      propsData: {
        options: {
          page: 4,
          itemsPerPage: 10,
        },
        pagination: {
          page: 4,
          itemsPerPage: 10,
          pageStart: 1,
          pageStop: 10,
          pageCount: 10,
          itemsLength: 100,
        },
        showFirstLastPage: true,
      },
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  it('should switch between pages', () => {
    const mock = jest.fn()

    const wrapper = mountFunction({
      propsData: {
        options: {
          page: 4,
          itemsPerPage: 10,
        },
        pagination: {
          page: 4,
          itemsPerPage: 10,
          pageStart: 1,
          pageStop: 10,
          pageCount: 10,
          itemsLength: 100,
        },
      },
      listeners: {
        'update:options': mock,
      },
    })

    wrapper.vm.onNextPage()
    expect(mock).toHaveBeenCalledWith({ itemsPerPage: 10, page: 5 })
    wrapper.vm.onPreviousPage()
    expect(mock).toHaveBeenCalledWith({ itemsPerPage: 10, page: 3 })
    wrapper.vm.onFirstPage()
    expect(mock).toHaveBeenCalledWith({ itemsPerPage: 10, page: 1 })
    wrapper.vm.onLastPage()
    expect(mock).toHaveBeenCalledWith({ itemsPerPage: 10, page: 10 })
    wrapper.vm.onChangeItemsPerPage(5)
    expect(mock).toHaveBeenCalledWith({ itemsPerPage: 5, page: 1 })
    wrapper.vm.onChangeItemsPerPage(20)
    expect(mock).toHaveBeenCalledWith({ itemsPerPage: 20, page: 1 })
  })

  it('should show current page if has showCurrentPage', () => {
    const wrapper = mountFunction({
      propsData: {
        options: {
          page: 4,
          itemsPerPage: 10,
        },
        pagination: {
          page: 4,
          itemsPerPage: 10,
          pageStart: 1,
          pageStop: 10,
          pageCount: 10,
          itemsLength: 100,
        },
        showCurrentPage: true,
      },
    })

    expect(wrapper.html()).toMatchSnapshot()
  })

  it('should disable last page button if no items', () => {
    const wrapper = mountFunction({
      propsData: {
        options: {
          page: 1,
          itemsPerPage: 10,
        },
        pagination: {
          page: 1,
          itemsPerPage: 10,
          pageStart: 0,
          pageStop: 0,
          pageCount: 0,
          itemsLength: 0,
        },
        showFirstLastPage: true,
      },
    })

    expect(wrapper.html()).toMatchSnapshot()
  })
})


const deepmerge = require('deepmerge')

function arrayMerge (a, b) {
  const arr = a.slice()
  for (let i = 0; i < b.length; i++) {
    const found = a.findIndex(item => item.name === b[i].name)
    if (found >= 0) {
      arr[found] = deepmerge(a[found], b[i])
    } else {
      arr.push(b[i])
    }
  }
  return arr
}

module.exports = function merge (...arr) {
  return deepmerge.all(arr, { arrayMerge })
}


$a: calc((var(--v-field-padding-top, 0) + var(--v-input-padding-top, 0)) - 6px)

keep keep keep add keep keep keep keep keep


// Utilities
import { makeDelayProps, useDelay } from '../delay'
import { mount } from '@vue/test-utils'
import { describe, expect, it } from '@jest/globals'
import { wait } from '../../../test'

describe('delayProps', () => {
  it('should allow setting default values', () => {
    const wrapper = mount({
      template: '<div />',
      props: makeDelayProps({
        closeDelay: 42,
        openDelay: 7,
      }),
    })

    expect(wrapper.props()).toStrictEqual({
      closeDelay: 42,
      openDelay: 7,
    })
  })
})

describe('useDelay', () => {
  it.each(['runOpenDelay', 'runCloseDelay'] as const)('should call %s - callback', async methodName => {
    const cb = jest.fn()
    const runDelay = useDelay({
      openDelay: 50,
      closeDelay: 50,
    }, cb)[methodName]

    runDelay()

    await wait(30)
    expect(cb).not.toHaveBeenCalled()

    await wait(30)
    expect(cb).toHaveBeenCalledWith(methodName === 'runOpenDelay')
  })

  it.each(['runOpenDelay', 'runCloseDelay'] as const)('should call %s - promise', async methodName => {
    const cb = jest.fn(val => val)
    const runDelay = useDelay({
      openDelay: 50,
      closeDelay: 50,
    })[methodName]

    const delay = runDelay().then(cb)

    await Promise.race([
      delay,
      wait(30),
    ])
    expect(cb).not.toHaveBeenCalled()

    await expect(delay).resolves.toBe(methodName === 'runOpenDelay')
  })

  it('should cancel delay when running a new one', async () => {
    const cb = jest.fn()
    const { runOpenDelay, runCloseDelay } = useDelay({
      closeDelay: 50,
      openDelay: 50,
    }, cb)

    runOpenDelay()
    await wait(30)
    runCloseDelay()
    await wait(60)

    expect(cb).toHaveBeenCalledTimes(1)
    expect(cb).toHaveBeenCalledWith(false)
  })
})


// VColorPicker
$color-picker-border-radius: 4px !default;
$color-picker-checkerboard: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAACRJREFUKFNjPHTo0H8GJGBnZ8eIzGekgwJk+0BsdCtRHEQbBQBbbh0dIGKknQAAAABJRU5ErkJggg==) repeat !default;
$color-picker-controls-padding: 16px !default;
$color-picker-elevation: 2 !default;
$color-picker-input-font-size: 0.75rem !default;
$color-picker-input-height: 32px !default;
$color-picker-input-margin: 8px !default;
$color-picker-preview-margin-bottom: 24px !default;
$color-picker-input-margin-bottom: 8px !default;

// VColorPickerSwatch
$color-picker-swatch-color-border-radius: 2px !default;
$color-picker-swatch-color-height: 18px !default;
$color-picker-swatch-color-margin: 2px 4px !default;
$color-picker-swatch-color-width: 45px !default;
$color-picker-swatch-margin-bottom: 10px !default;
$color-picker-swatches-border-radius: 8px !default;

// VColorCanvas
$color-picker-canvas-dot-box-shadow: 0px 0px 0px 1.5px rgba(255, 255, 255, 1), inset 0px 0px 1px 1.5px rgba(0, 0, 0, 0.3) !default;
$color-picker-canvas-dot-disabled-box-shadow: 0px 0px 0px 1.5px rgba(255, 255, 255, 0.7), inset 0px 0px 1px 1.5px rgba(0, 0, 0, 0.3) !default;
$color-picker-canvas-dot-size: 15px !default;

// VColorPickerPreview
$color-picker-preview-dot-size: 30px !default;
$color-picker-preview-dot-margin: 24px !default;


module.exports = {
  'v-stepper-items': {
    slots: [
      {
        name: 'default',
        props: undefined,
      },
    ],
  },
}


height: 0 !important
min-height: 0 !important
pointer-events: none
.v-field--has-label
textarea
opacity: 0
.v-field--active
textarea
opacity: 1

keep keep keep keep replace replace replace replace keep keep keep keep

@use 'sass:selector'
@use '../../styles/settings'
@use './variables' as *

/* region BLOCK */
.v-text-field
  input
    color: inherit
    flex: $text-field-input-flex
    transition: $text-field-input-transition
    min-width: 0

    &:focus,
    &:active
      outline: none

    // Remove Firefox red outline
    &:invalid
      box-shadow: none

  .v-field
    cursor: text

  .v-field__input
    @at-root #{selector.append('.v-text-field--prefixed', &)}
      --v-field-padding-start: #{$text-field-input-padding-start}

    @at-root #{selector.append('.v-text-field--suffixed', &)}
      --v-field-padding-end: #{$text-field-input-padding-end}

  .v-input__details
    padding-inline-start: $text-field-details-padding-inline
    padding-inline-end: $text-field-details-padding-inline

  .v-field--has-label
    input
      opacity: 0

  .v-field--active
    input
      opacity: 1

  .v-field--single-line
    input
      transition: none

/* endregion */
/* region ELEMENTS */
.v-text-field
  &__prefix,
  &__suffix
    align-items: center
    color: $text-field-affix-color
    cursor: default
    display: flex
    opacity: 0
    transition: inherit
    white-space: nowrap
    padding-top: calc(var(--v-field-padding-top, 4px) + var(--v-input-padding-top, 0))
    padding-bottom: var(--v-field-padding-bottom, 6px)

    .v-field--active &
      opacity: 1

    .v-field--disabled &
      color: $text-field-disabled-affix-color

  &__prefix
    padding-inline-start: var(--v-field-padding-start)

  &__suffix
    padding-inline-end: var(--v-field-padding-end)

/* endregion */
/* region MODIFIERS */
.v-text-field
  &--flush-details
    .v-input__details
      padding: 0
/* endregion */


export { VChipGroup } from './VChipGroup'


module.exports = {
  'v-lazy': {
    slots: [
      {
        name: 'default',
        props: undefined,
      },
    ],
  },
}


@use 'sass:math';
@use 'sass:map';
@use '../../styles/settings';
@use '../../styles/tools';

// Defaults
/** if false, disabled buttons will be greyed out */
$button-colored-disabled: true !default;

$button-app-bar-elevation: 0 !default;
$button-background: rgb(var(--v-theme-surface)) !default;
$button-color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity)) !default;
$button-banner-actions-padding: 0 8px !default;
$button-pagination-active-overlay-opacity: var(--v-border-opacity) !default;
$button-pagination-border-radius: settings.$border-radius-root !default;
$button-border-color: settings.$border-color-root !default;
$button-border-radius: settings.$border-radius-root !default;
$button-border-style: settings.$border-style-root !default;
$button-border-thin-width: thin !default;
$button-border-width: 0 !default;
$button-card-actions-elevation: 0 !default;
$button-card-actions-margin: .5rem !default;
$button-card-actions-padding: 0 8px !default;
$button-content-transition: transform, opacity .2s settings.$standard-easing !default;
$button-disabled-opacity: 0.26 !default;
$button-disabled-overlay: 0.12 !default;
$button-elevation: ('default': 2, 'hover': 4, 'active': 8) !default;
$button-font-size: tools.map-deep-get(settings.$typography, 'button', 'size') !default;
$button-font-weight: tools.map-deep-get(settings.$typography, 'button', 'weight') !default;
$button-height: 36px !default;
$button-stacked-height: 72px !default;
$button-stacked-icon-margin: 4px !default;
$button-icon-border-radius: map.get(settings.$rounded, 'circle') !default;
$button-icon-font-size: 1rem !default;
$button-line-height: normal !default;
$button-stacked-line-height: 1.25 !default;
$button-plain-opacity: .62 !default;
$button-padding-ratio: 2.25 !default;
$button-stacked-padding-ratio: 4.5 !default;
$button-margin-start-multiplier: -9 !default;
$button-margin-end-multiplier: 4.5 !default;
$button-margin-start: calc(var(--v-btn-height) / #{$button-margin-start-multiplier}) !default;
$button-margin-end: calc(var(--v-btn-height) / #{$button-margin-end-multiplier}) !default;
$button-max-width: 100% !default;
$button-positions: absolute fixed !default;
$button-text-letter-spacing: tools.map-deep-get(settings.$typography, 'button', 'letter-spacing') !default;
$button-text-transform: tools.map-deep-get(settings.$typography, 'button', 'text-transform') !default;
$button-transition-property: box-shadow, transform, opacity, background !default;
$button-vertical-align: middle !default;
$button-width-ratio: math.div(16, 9) !default;
$button-snackbar-action-padding: 0 8px !default;
$button-stacked-width-ratio: 1 !default;
$button-rounded-border-radius: map.get(settings.$rounded, 'xl') !default;
$button-white-space: nowrap !default;

$button-density: ('default': 0, 'comfortable': -2, 'compact': -3) !default;
$button-stacked-density: ('default': 0, 'comfortable': -4, 'compact': -6) !default;
$button-icon-density: ('default': 3, 'comfortable': 0, 'compact': -2) !default;

$button-border: (
  $button-border-color,
  $button-border-style,
  $button-border-width,
  $button-border-thin-width
) !default;

$button-sizes: () !default;
$button-sizes: map.merge(
    (
      'height': $button-height,
      'font-size': $button-font-size,
      'width-ratio': $button-width-ratio,
      'padding-ratio': $button-padding-ratio
    ),
    $button-sizes
);

$button-stacked-sizes: () !default;
$button-stacked-sizes: map.merge(
    (
      'height': $button-stacked-height,
      'font-size': $button-font-size,
      'width-ratio': $button-stacked-width-ratio,
      'padding-ratio': $button-stacked-padding-ratio
    ),
    $button-stacked-sizes
);

$button-variants: (
  $button-background,
  $button-color,
  map.get($button-elevation, 'default'),
  $button-plain-opacity,
  'v-btn'
);


transition: .15s opacity settings.$standard-easing


module.exports = {
  argument: [
    {
      name: 'argument',
      type: [
        'object',
      ],
      example: {
        center: 'boolean',
        class: 'string',
      },
    },
  ],
  props: [],
}


Adds indentation (72px) for **normal** dividers, reduces max height for **vertical**.

Sets the dividers length. Default unit is px.

Sets the dividers thickness. Default unit is px.


module.exports = {
  'v-tab-item': {
    slots: [
      {
        name: 'default',
        props: undefined,
      },
    ],
  },
}


const filteredLength = this.filteredPackages.length;

const packageCountLabel = `${filteredLength} package${filteredLength > 1 ? "s" : ""}`;

// root install does not need progress bar

keep keep keep keep replace replace keep keep keep keep keep

"use strict";

const _ = require("lodash");
const dedent = require("dedent");
const execa = require("execa");
const log = require("libnpm/log");

const PackageGraph = require("@lerna/package-graph");
const Project = require("@lerna/project");
const writeLogFile = require("@lerna/write-log-file");
const ValidationError = require("@lerna/validation-error");

const cleanStack = require("./lib/clean-stack");
const logPackageError = require("./lib/log-package-error");
const warnIfHanging = require("./lib/warn-if-hanging");

const DEFAULT_CONCURRENCY = 4;

class Command {
  constructor(argv) {
    log.pause();
    log.heading = "lerna";

    log.silly("argv", argv);

    // "FooCommand" => "foo"
    this.name = this.constructor.name.replace(/Command$/, "").toLowerCase();

    // composed commands are called from other commands, like publish -> version
    this.composed = typeof argv.composed === "string" && argv.composed !== this.name;

    if (!this.composed) {
      // composed commands have already logged the lerna version
      log.notice("cli", `v${argv.lernaVersion}`);
    }

    // launch the command
    let runner = new Promise((resolve, reject) => {
      // run everything inside a Promise chain
      let chain = Promise.resolve();

      chain = chain.then(() => {
        this.project = new Project(argv.cwd);
      });
      chain = chain.then(() => this.configureEnvironment());
      chain = chain.then(() => this.configureOptions());
      chain = chain.then(() => this.configureProperties());
      chain = chain.then(() => this.configureLogging());
      chain = chain.then(() => this.runValidations());
      chain = chain.then(() => this.runPreparations());
      chain = chain.then(() => this.runCommand());

      chain.then(
        result => {
          warnIfHanging();

          resolve(result);
        },
        err => {
          if (err.pkg) {
            // Cleanly log specific package error details
            logPackageError(err, this.options.stream);
          } else if (err.name !== "ValidationError") {
            // npmlog does some funny stuff to the stack by default,
            // so pass it directly to avoid duplication.
            log.error("", cleanStack(err, this.constructor.name));
          }

          // ValidationError does not trigger a log dump, nor do external package errors
          if (err.name !== "ValidationError" && !err.pkg) {
            writeLogFile(this.project.rootPath);
          }

          warnIfHanging();

          // error code is handled by cli.fail()
          reject(err);
        }
      );
    });

    // passed via yargs context in tests, never actual CLI
    /* istanbul ignore else */
    if (argv.onResolved || argv.onRejected) {
      runner = runner.then(argv.onResolved, argv.onRejected);

      // when nested, never resolve inner with outer callbacks
      delete argv.onResolved; // eslint-disable-line no-param-reassign
      delete argv.onRejected; // eslint-disable-line no-param-reassign
    }

    // "hide" irrelevant argv keys from options
    for (const key of ["cwd", "$0"]) {
      Object.defineProperty(argv, key, { enumerable: false });
    }

    Object.defineProperty(this, "argv", {
      value: Object.freeze(argv),
    });

    Object.defineProperty(this, "runner", {
      value: runner,
    });
  }

  // proxy "Promise" methods to "private" instance
  then(onResolved, onRejected) {
    return this.runner.then(onResolved, onRejected);
  }

  /* istanbul ignore next */
  catch(onRejected) {
    return this.runner.catch(onRejected);
  }

  get requiresGit() {
    return true;
  }

  // Override this to inherit config from another command.
  // For example `changed` inherits config from `publish`.
  get otherCommandConfigs() {
    return [];
  }

  configureEnvironment() {
    // eslint-disable-next-line global-require
    const ci = require("is-ci");
    let loglevel;
    let progress;

    /* istanbul ignore next */
    if (ci || !process.stderr.isTTY) {
      log.disableColor();
      progress = false;
    } else if (!process.stdout.isTTY) {
      // stdout is being piped, don't log non-errors or progress bars
      progress = false;
      loglevel = "error";
    } else if (process.stderr.isTTY) {
      log.enableColor();
      log.enableUnicode();
    }

    Object.defineProperty(this, "envDefaults", {
      value: {
        ci,
        progress,
        loglevel,
      },
    });
  }

  configureOptions() {
    // Command config object normalized to "command" namespace
    const commandConfig = this.project.config.command || {};

    // The current command always overrides otherCommandConfigs
    const overrides = [this.name, ...this.otherCommandConfigs].map(key => commandConfig[key]);

    this.options = _.defaults(
      {},
      // CLI flags, which if defined overrule subsequent values
      this.argv,
      // Namespaced command options from `lerna.json`
      ...overrides,
      // Global options from `lerna.json`
      this.project.config,
      // Environmental defaults prepared in previous step
      this.envDefaults
    );
  }

  configureProperties() {
    const { concurrency, sort, maxBuffer } = this.options;

    this.concurrency = Math.max(1, +concurrency || DEFAULT_CONCURRENCY);
    this.toposort = sort === undefined || sort;
    this.execOpts = {
      cwd: this.project.rootPath,
      maxBuffer,
    };
  }

  configureLogging() {
    const { loglevel } = this.options;

    if (loglevel) {
      log.level = loglevel;
    }

    // handle log.success()
    log.addLevel("success", 3001, { fg: "green", bold: true });

    // create logger that subclasses use
    Object.defineProperty(this, "logger", {
      value: log.newGroup(this.name),
    });

    // emit all buffered logs at configured level and higher
    log.resume();
  }

  enableProgressBar() {
    /* istanbul ignore next */
    if (this.options.progress) {
      log.enableProgress();
    }
  }

  gitInitialized() {
    const opts = {
      cwd: this.project.rootPath,
      // don't throw, just want boolean
      reject: false,
      // only return code, no stdio needed
      stdio: "ignore",
    };

    return execa.sync("git", ["rev-parse"], opts).code === 0;
  }

  runValidations() {
    if ((this.options.since !== undefined || this.requiresGit) && !this.gitInitialized()) {
      throw new ValidationError("ENOGIT", "The git binary was not found, or this is not a git repository.");
    }

    if (!this.project.manifest) {
      throw new ValidationError("ENOPKG", "`package.json` does not exist, have you run `lerna init`?");
    }

    if (!this.project.version) {
      throw new ValidationError("ENOLERNA", "`lerna.json` does not exist, have you run `lerna init`?");
    }

    if (this.options.independent && !this.project.isIndependent()) {
      throw new ValidationError(
        "EVERSIONMODE",
        dedent`
          You ran lerna with --independent or -i, but the repository is not set to independent mode.
          To use independent mode you need to set lerna.json's "version" property to "independent".
          Then you won't need to pass the --independent or -i flags.
        `
      );
    }
  }

  runPreparations() {
    if (!this.composed && this.project.isIndependent()) {
      // composed commands have already logged the independent status
      log.info("versioning", "independent");
    }

    if (!this.composed && this.options.ci) {
      log.info("ci", "enabled");
    }

    let chain = Promise.resolve();

    chain = chain.then(() => this.project.getPackages());
    chain = chain.then(packages => {
      this.packageGraph = new PackageGraph(packages);
    });

    return chain;
  }

  runCommand() {
    return Promise.resolve()
      .then(() => this.initialize())
      .then(proceed => {
        if (proceed !== false) {
          return this.execute();
        }
        // early exits set their own exitCode (if non-zero)
      });
  }

  initialize() {
    throw new ValidationError(this.name, "initialize() needs to be implemented.");
  }

  execute() {
    throw new ValidationError(this.name, "execute() needs to be implemented.");
  }
}

module.exports = Command;


/**
 * Prints out the package name and any passed args, followed by
 * all the files in this directory
 * eg
 * package-1 -1
 * file1.js
 * package.json
 */
const path = require("path");
const fs = require("fs");

const cwd = process.cwd();
const parsedCwd = path.basename(cwd);

// The first two elements in process.argv are the path to node and this script, don't include them
// as they will be different on each platform/device
const passedArgs = process.argv.slice(2).join(" ");

// List all files in the current directory and filter out the exec-test* files
// to focus on the files under test
const files = fs
  .readdirSync(cwd)
  .filter(file => file.indexOf("exec-test") === -1)
  .join("\n");

console.log(`--> in "${parsedCwd}" with extra args "${passedArgs}"`);
console.log(files);


"use strict";

const execa = require("execa");

module.exports = getCommitMessage;

function getCommitMessage(cwd, format = "%B") {
  return execa.stdout("git", ["log", "-1", `--pretty=format:${format}`], { cwd });
}


keep keep keep keep replace replace keep keep keep keep

"use strict";

const path = require("path");
const pMap = require("p-map");

const Command = require("@lerna/command");
const rimrafDir = require("@lerna/rimraf-dir");
const PromptUtilities = require("@lerna/prompt");
const { getFilteredPackages } = require("@lerna/filter-options");
const pulseTillDone = require("@lerna/pulse-till-done");

module.exports = factory;

function factory(argv) {
  return new CleanCommand(argv);
}

class CleanCommand extends Command {
  get requiresGit() {
    return false;
  }

  initialize() {
    let chain = Promise.resolve();

    chain = chain.then(() => getFilteredPackages(this.packageGraph, this.execOpts, this.options));
    chain = chain.then(filteredPackages => {
      this.directoriesToDelete = filteredPackages.map(pkg => pkg.nodeModulesLocation);
    });

    return chain.then(() => {
      if (this.options.yes) {
        return true;
      }

      this.logger.info("", "Removing the following directories:");
      this.logger.info(
        "clean",
        this.directoriesToDelete.map(dir => path.relative(this.project.rootPath, dir)).join("\n")
      );

      return PromptUtilities.confirm("Proceed?");
    });
  }

  execute() {
    this.enableProgressBar();

    const tracker = this.logger.newItem("clean");
    const mapper = dirPath => {
      tracker.info("clean", "removing", dirPath);

      return pulseTillDone(rimrafDir(dirPath)).then(() => {
        tracker.completeWork(1);
      });
    };

    tracker.addWork(this.directoriesToDelete.length);

    return pMap(this.directoriesToDelete, mapper, { concurrency: this.concurrency }).then(() => {
      tracker.finish();
      this.logger.success("clean", "finished");
    });
  }
}

module.exports.CleanCommand = CleanCommand;


"use strict";

const log = require("libnpm/log");
const npa = require("libnpm/parse-arg");
const childProcess = require("@lerna/child-process");

module.exports = getCurrentTags;

function getCurrentTags(execOpts, matchingPattern) {
  log.silly("getCurrentTags");

  const opts = Object.assign({}, execOpts, {
    // don't reject due to non-zero exit code when there are no results
    reject: false,
  });

  return childProcess
    .exec("git", ["tag", "--sort", "version:refname", "--points-at", "HEAD", "--list", matchingPattern], opts)
    .then(listPackageNames);
}

function listPackageNames(result) {
  return result.stdout
    .split("\n")
    .map(tag => tag && npa(tag).name)
    .filter(Boolean);
}


.replace(/^(copy (from|to)) /gm, `$1 ${formattedTarget}/`)

.replace(/^(rename (from|to)) /gm, `$1 ${formattedTarget}/`);

const tracker = this.logger.newItem("execute");

const patch = this.createPatchForCommit(sha);

keep keep keep keep keep replace replace keep keep keep keep keep


this.logger.info("publish", "Publishing packages to npm...");

keep keep keep replace keep keep keep keep

"use strict";

const dedent = require("dedent");
const getPort = require("get-port");
const npa = require("libnpm/parse-arg");
const path = require("path");
const pFinally = require("p-finally");
const pMap = require("p-map");
const pMapSeries = require("p-map-series");
const pWaterfall = require("p-waterfall");

const Command = require("@lerna/command");
const rimrafDir = require("@lerna/rimraf-dir");
const hasNpmVersion = require("@lerna/has-npm-version");
const npmInstall = require("@lerna/npm-install");
const { createRunner } = require("@lerna/run-lifecycle");
const batchPackages = require("@lerna/batch-packages");
const runParallelBatches = require("@lerna/run-parallel-batches");
const symlinkBinary = require("@lerna/symlink-binary");
const symlinkDependencies = require("@lerna/symlink-dependencies");
const ValidationError = require("@lerna/validation-error");
const { getFilteredPackages } = require("@lerna/filter-options");
const PackageGraph = require("@lerna/package-graph");
const pulseTillDone = require("@lerna/pulse-till-done");

const hasDependencyInstalled = require("./lib/has-dependency-installed");
const isHoistedPackage = require("./lib/is-hoisted-package");

module.exports = factory;

function factory(argv) {
  return new BootstrapCommand(argv);
}

class BootstrapCommand extends Command {
  get requiresGit() {
    return false;
  }

  initialize() {
    const { registry, npmClient = "npm", npmClientArgs, mutex, hoist } = this.options;

    if (npmClient === "yarn" && hoist) {
      throw new ValidationError(
        "EWORKSPACES",
        dedent`
            --hoist is not supported with --npm-client=yarn, use yarn workspaces instead
            A guide is available at https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/
          `
      );
    }

    if (
      npmClient === "yarn" &&
      this.project.manifest.get("workspaces") &&
      this.options.useWorkspaces !== true
    ) {
      throw new ValidationError(
        "EWORKSPACES",
        dedent`
            Yarn workspaces are configured in package.json, but not enabled in lerna.json!
            Please choose one: useWorkspaces = true in lerna.json, or remove package.json workspaces config
          `
      );
    }

    this.runPackageLifecycle = createRunner({ registry });
    this.npmConfig = {
      registry,
      npmClient,
      npmClientArgs,
      mutex,
    };

    if (npmClient === "npm" && this.options.ci && hasNpmVersion(">=5.7.0")) {
      this.npmConfig.subCommand = "ci";
    }

    // lerna bootstrap ... -- <input>
    const doubleDashArgs = this.options["--"] || [];
    if (doubleDashArgs.length) {
      this.npmConfig.npmClientArgs = [...(npmClientArgs || []), ...doubleDashArgs];
    }

    this.targetGraph = this.options.forceLocal
      ? new PackageGraph(this.packageGraph.rawPackageList, "allDependencies", "forceLocal")
      : this.packageGraph;

    let chain = Promise.resolve();

    chain = chain.then(() => getFilteredPackages(this.targetGraph, this.execOpts, this.options));
    chain = chain.then(filteredPackages => {
      this.filteredPackages = filteredPackages;
    });

    chain = chain.then(() => {
      this.batchedPackages = this.toposort
        ? batchPackages(this.filteredPackages, this.options.rejectCycles)
        : [this.filteredPackages];

      if (npmClient === "yarn" && !mutex) {
        return getPort({ port: 42424, host: "0.0.0.0" }).then(port => {
          this.npmConfig.mutex = `network:${port}`;
          this.logger.silly("npmConfig", this.npmConfig);
        });
      }

      this.logger.silly("npmConfig", this.npmConfig);
    });

    return chain;
  }

  execute() {
    if (this.options.useWorkspaces || this.rootHasLocalFileDependencies()) {
      return this.installRootPackageOnly();
    }

    const filteredLength = this.filteredPackages.length;
    const packageCountLabel = `${filteredLength} package${filteredLength > 1 ? "s" : ""}`;

    // root install does not need progress bar
    this.enableProgressBar();
    this.logger.info("", `Bootstrapping ${packageCountLabel}`);

    const tasks = [
      () => this.getDependenciesToInstall(),
      result => this.installExternalDependencies(result),
      () => this.symlinkPackages(),
    ];

    if (!this.options.ignoreScripts) {
      tasks.unshift(() => this.preinstallPackages());
      // then install
      // then symlink
      tasks.push(
        () => this.postinstallPackages(),
        () => this.prepublishPackages(),
        () => this.preparePackages()
      );
    }

    return pWaterfall(tasks).then(() => {
      this.logger.success("", `Bootstrapped ${packageCountLabel}`);
    });
  }

  installRootPackageOnly() {
    this.logger.info("bootstrap", "root only");

    // don't hide yarn or npm output
    this.npmConfig.stdio = "inherit";

    return npmInstall(this.project.manifest, this.npmConfig);
  }

  /**
   * If the root manifest has local dependencies with `file:` specifiers,
   * all the complicated bootstrap logic should be skipped in favor of
   * npm5's package-locked auto-hoisting.
   * @returns {Boolean}
   */
  rootHasLocalFileDependencies() {
    const rootDependencies = Object.assign({}, this.project.manifest.dependencies);

    return Object.keys(rootDependencies).some(
      name =>
        this.targetGraph.has(name) &&
        npa.resolve(name, rootDependencies[name], this.project.rootPath).type === "directory"
    );
  }

  runLifecycleInPackages(stage) {
    this.logger.verbose("lifecycle", stage);

    if (!this.filteredPackages.length) {
      return;
    }

    const tracker = this.logger.newItem(stage);

    const mapPackageWithScript = pkg =>
      this.runPackageLifecycle(pkg, stage).then(() => {
        tracker.silly("lifecycle", "finished %j in %s", stage, pkg.name);
        tracker.completeWork(1);
      });

    tracker.addWork(this.filteredPackages.length);

    return pFinally(runParallelBatches(this.batchedPackages, this.concurrency, mapPackageWithScript), () =>
      tracker.finish()
    );
  }

  /**
   * Run the "preinstall" NPM script in all bootstrapped packages
   * @returns {Promise}
   */
  preinstallPackages() {
    return this.runLifecycleInPackages("preinstall");
  }

  /**
   * Run the "postinstall" NPM script in all bootstrapped packages
   * @returns {Promise}
   */
  postinstallPackages() {
    return this.runLifecycleInPackages("postinstall");
  }

  /**
   * Run the "prepublish" NPM script in all bootstrapped packages
   * @returns {Promise}
   */
  prepublishPackages() {
    return this.runLifecycleInPackages("prepublish");
  }

  /**
   * Run the "prepare" NPM script in all bootstrapped packages
   * @returns {Promise}
   */
  preparePackages() {
    return this.runLifecycleInPackages("prepare");
  }

  hoistedDirectory(dependency) {
    return path.join(this.project.rootPath, "node_modules", dependency);
  }

  hoistedPackageJson(dependency) {
    try {
      // eslint-disable-next-line import/no-dynamic-require, global-require
      return require(path.join(this.hoistedDirectory(dependency), "package.json"));
    } catch (e) {
      // Pass.
      return {};
    }
  }

  /**
   * Return a object of root and leaf dependencies to install
   * @returns {Object}
   */
  getDependenciesToInstall() {
    // Configuration for what packages to hoist may be in lerna.json or it may
    // come in as command line options.
    const { hoist, nohoist } = this.options;
    const rootPkg = this.project.manifest;

    let hoisting;

    if (hoist) {
      if (hoist === true) {
        // lerna.json `hoist: true`
        hoisting = ["**"];
      } else {
        // `--hoist ...` or lerna.json `hoist: [...]`
        hoisting = [].concat(hoist);
      }

      if (nohoist) {
        if (!Array.isArray(nohoist)) {
          // `--nohoist` single
          hoisting = hoisting.concat(`!${nohoist}`);
        } else {
          // `--nohoist` multiple or lerna.json `nohoist: [...]`
          hoisting = hoisting.concat(nohoist.map(str => `!${str}`));
        }
      }

      this.logger.verbose("hoist", "using globs %j", hoisting);
    }

    // This will contain entries for each hoistable dependency.
    const rootSet = new Set();

    // This will map packages to lists of unhoistable dependencies
    const leaves = new Map();

    /**
     * Map of dependencies to install
     *
     * Map {
     *   "<externalName>": Map {
     *     "<versionRange>": Set { "<dependent1>", "<dependent2>", ... }
     *   }
     * }
     *
     * Example:
     *
     * Map {
     *   "react": Map {
     *     "15.x": Set { "my-component1", "my-component2", "my-component3" },
     *     "^0.14.0": Set { "my-component4" },
     *   }
     * }
     */
    const depsToInstall = new Map();
    const filteredNodes = new Map(
      this.filteredPackages.map(pkg => [pkg.name, this.targetGraph.get(pkg.name)])
    );

    // collect root dependency versions
    const mergedRootDeps = Object.assign(
      {},
      rootPkg.devDependencies,
      rootPkg.optionalDependencies,
      rootPkg.dependencies
    );
    const rootExternalVersions = new Map(
      Object.keys(mergedRootDeps).map(externalName => [externalName, mergedRootDeps[externalName]])
    );

    // seed the root dependencies
    rootExternalVersions.forEach((version, externalName) => {
      const externalDependents = new Set();
      const record = new Map();

      record.set(version, externalDependents);
      depsToInstall.set(externalName, record);
    });

    // build a map of external dependencies to install
    for (const [leafName, leafNode] of filteredNodes) {
      for (const [externalName, resolved] of leafNode.externalDependencies) {
        // rawSpec is something like "^1.2.3"
        const version = resolved.rawSpec;
        const record =
          depsToInstall.get(externalName) || depsToInstall.set(externalName, new Map()).get(externalName);
        const externalDependents = record.get(version) || record.set(version, new Set()).get(version);

        externalDependents.add(leafName);
      }
    }

    const rootActions = [];
    const leafActions = [];

    // determine where each dependency will be installed
    for (const [externalName, externalDependents] of depsToInstall) {
      let rootVersion;

      if (hoisting && isHoistedPackage(externalName, hoisting)) {
        const commonVersion = Array.from(externalDependents.keys()).reduce((a, b) =>
          externalDependents.get(a).size > externalDependents.get(b).size ? a : b
        );

        // Get the version required by the repo root (if any).
        // If the root doesn't have a dependency on this package then we'll
        // install the most common dependency there.
        rootVersion = rootExternalVersions.get(externalName) || commonVersion;

        if (rootVersion !== commonVersion) {
          this.logger.warn(
            "EHOIST_ROOT_VERSION",
            `The repository root depends on ${externalName}@${rootVersion}, ` +
              `which differs from the more common ${externalName}@${commonVersion}.`
          );
        }

        const dependents = Array.from(externalDependents.get(rootVersion)).map(
          leafName => this.targetGraph.get(leafName).pkg
        );

        // remove collection so leaves don't repeat it
        externalDependents.delete(rootVersion);

        // Install the best version we can in the repo root.
        // Even if it's already installed there we still need to make sure any
        // binaries are linked to the packages that depend on them.
        rootActions.push(() =>
          hasDependencyInstalled(rootPkg, externalName, rootVersion).then(isSatisfied => {
            rootSet.add({
              name: externalName,
              dependents,
              dependency: `${externalName}@${rootVersion}`,
              isSatisfied,
            });
          })
        );
      }

      // Add less common versions to package installs.
      for (const [leafVersion, leafDependents] of externalDependents) {
        for (const leafName of leafDependents) {
          if (rootVersion) {
            this.logger.warn(
              "EHOIST_PKG_VERSION",
              `"${leafName}" package depends on ${externalName}@${leafVersion}, ` +
                `which differs from the hoisted ${externalName}@${rootVersion}.`
            );
          }

          const leafNode = this.targetGraph.get(leafName);
          const leafRecord = leaves.get(leafNode) || leaves.set(leafNode, new Set()).get(leafNode);

          // only install dependency if it's not already installed
          leafActions.push(() =>
            hasDependencyInstalled(leafNode.pkg, externalName, leafVersion).then(isSatisfied => {
              leafRecord.add({
                dependency: `${externalName}@${leafVersion}`,
                isSatisfied,
              });
            })
          );
        }
      }
    }

    return pMapSeries([...rootActions, ...leafActions], el => el()).then(() => {
      this.logger.silly("root dependencies", JSON.stringify(rootSet, null, 2));
      this.logger.silly("leaf dependencies", JSON.stringify(leaves, null, 2));

      return { rootSet, leaves };
    });
  }

  /**
   * Install external dependencies for all packages
   * @returns {Promise}
   */
  installExternalDependencies({ leaves, rootSet }) {
    const tracker = this.logger.newItem("install dependencies");
    const rootPkg = this.project.manifest;
    const actions = [];

    // Start root install first, if any, since it's likely to take the longest.
    if (rootSet.size) {
      // If we have anything to install in the root then we'll install
      // _everything_ that needs to go there.  This is important for
      // consistent behavior across npm clients.
      const root = Array.from(rootSet);

      actions.push(() => {
        const depsToInstallInRoot = root.some(({ isSatisfied }) => !isSatisfied)
          ? root.map(({ dependency }) => dependency)
          : [];

        if (depsToInstallInRoot.length) {
          tracker.info("hoist", "Installing hoisted dependencies into root");
        }

        const promise = npmInstall.dependencies(rootPkg, depsToInstallInRoot, this.npmConfig);

        return pulseTillDone(promise)
          .then(() =>
            // Link binaries into dependent packages so npm scripts will
            // have access to them.
            pMapSeries(root, ({ name, dependents }) => {
              const { bin } = this.hoistedPackageJson(name);

              if (bin) {
                return pMap(dependents, pkg => {
                  const src = this.hoistedDirectory(name);

                  return symlinkBinary(src, pkg);
                });
              }
            })
          )
          .then(() => {
            tracker.info("hoist", "Finished bootstrapping root");
            tracker.completeWork(1);
          });
      });

      // Remove any hoisted dependencies that may have previously been
      // installed in package directories.
      actions.push(() => {
        // Compute the list of candidate directories synchronously
        const candidates = root
          .filter(dep => dep.dependents.length)
          .reduce((list, { name, dependents }) => {
            const dirs = dependents
              .filter(pkg => pkg.nodeModulesLocation !== rootPkg.nodeModulesLocation)
              .map(pkg => path.join(pkg.nodeModulesLocation, name));

            return list.concat(dirs);
          }, []);

        if (!candidates.length) {
          tracker.verbose("hoist", "nothing to prune");
          tracker.completeWork(1); // the action "work"

          return;
        }

        tracker.info("hoist", "Pruning hoisted dependencies");
        tracker.silly("prune", candidates);
        tracker.addWork(candidates.length);

        return pMap(
          candidates,
          dirPath =>
            pulseTillDone(rimrafDir(dirPath)).then(() => {
              tracker.verbose("prune", dirPath);
              tracker.completeWork(1);
            }),
          // these are mostly no-ops in the vast majority of cases
          { concurrency: this.concurrency }
        ).then(() => {
          tracker.info("hoist", "Finished pruning hoisted dependencies");
          tracker.completeWork(1); // the action "work"
        });
      });
    }

    const leafNpmConfig = Object.assign({}, this.npmConfig, {
      // Use `npm install --global-style` for leaves when hoisting is enabled
      npmGlobalStyle: !!this.options.hoist,
    });

    // Install anything that needs to go into the leaves.
    leaves.forEach((leafRecord, leafNode) => {
      const deps = Array.from(leafRecord);

      // If we have any unsatisfied deps then we need to install everything.
      // This is important for consistent behavior across npm clients.
      if (deps.some(({ isSatisfied }) => !isSatisfied)) {
        actions.push(() => {
          const dependencies = deps.map(({ dependency }) => dependency);
          const promise = npmInstall.dependencies(leafNode.pkg, dependencies, leafNpmConfig);

          return pulseTillDone(promise).then(() => {
            tracker.verbose("installed leaf", leafNode.name);
            tracker.completeWork(1);
          });
        });
      }
    });

    if (actions.length) {
      tracker.info("", "Installing external dependencies");
      tracker.verbose("actions", "%d actions, concurrency %d", actions.length, this.concurrency);
      tracker.addWork(actions.length);
    }

    return pFinally(pMap(actions, act => act(), { concurrency: this.concurrency }), () => tracker.finish());
  }

  /**
   * Symlink all packages to the packages/node_modules directory
   * Symlink package binaries to dependent packages' node_modules/.bin directory
   * @returns {Promise}
   */
  symlinkPackages() {
    return symlinkDependencies(this.filteredPackages, this.targetGraph, this.logger);
  }
}

module.exports.BootstrapCommand = BootstrapCommand;


};
}
configureLogging() {
const { loglevel } = this.options;
if (loglevel) {
log.level = loglevel;
}

keep keep keep keep replace keep keep keep keep keep

const { loglevel, progress = true } = this.options;


"use strict";

const cmdShim = require("cmd-shim");
const fs = require("fs-extra");
const log = require("libnpm/log");
const path = require("path");

module.exports = createSymlink;

function createSymlink(src, dest, type) {
  log.silly("createSymlink", [src, dest, type]);

  if (process.platform === "win32") {
    return createWindowsSymlink(src, dest, type);
  }

  return createPosixSymlink(src, dest, type);
}

function createSymbolicLink(src, dest, type) {
  log.silly("createSymbolicLink", [src, dest, type]);

  return fs
    .lstat(dest)
    .then(() => fs.unlink(dest))
    .catch(() => {
      /* nothing exists at destination */
    })
    .then(() => fs.symlink(src, dest, type));
}

function createPosixSymlink(origin, dest, _type) {
  const type = _type === "exec" ? "file" : _type;
  const src = path.relative(path.dirname(dest), origin);

  return createSymbolicLink(src, dest, type);
}

function createWindowsSymlink(src, dest, type) {
  if (type === "exec") {
    return new Promise((resolve, reject) => {
      cmdShim(src, dest, err => {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  }

  return createSymbolicLink(src, dest, type);
}


"use strict";

module.exports = {
  headerPattern: /^(\w*)(?:\((.*)\))?: (.*)$/,
  headerCorrespondence: [`type`, `scope`, `subject`],
  noteKeywords: [`BREAKING CHANGE`],
  revertPattern: /^revert:\s([\s\S]*?)\s*This reverts commit (\w*)\./,
  revertCorrespondence: [`header`, `hash`],
};


log.addLevel("success", 3001, { fg: "green", bold: true });

/* istanbul ignore next */
if (progress) {
log.enableProgress();
}

"use strict";

const os = require("os");
const path = require("path");
const crypto = require("crypto");
const pFinally = require("p-finally");
const pMap = require("p-map");
const pPipe = require("p-pipe");
const pReduce = require("p-reduce");
const semver = require("semver");
const getAuth = require("npm-registry-fetch/auth");

const Command = require("@lerna/command");
const describeRef = require("@lerna/describe-ref");
const checkWorkingTree = require("@lerna/check-working-tree");
const PromptUtilities = require("@lerna/prompt");
const output = require("@lerna/output");
const collectUpdates = require("@lerna/collect-updates");
const npmConf = require("@lerna/npm-conf");
const npmDistTag = require("@lerna/npm-dist-tag");
const npmPublish = require("@lerna/npm-publish");
const packDirectory = require("@lerna/pack-directory");
const logPacked = require("@lerna/log-packed");
const { createRunner } = require("@lerna/run-lifecycle");
const batchPackages = require("@lerna/batch-packages");
const runParallelBatches = require("@lerna/run-parallel-batches");
const pulseTillDone = require("@lerna/pulse-till-done");
const versionCommand = require("@lerna/version");

const createTempLicenses = require("./lib/create-temp-licenses");
const getCurrentSHA = require("./lib/get-current-sha");
const getCurrentTags = require("./lib/get-current-tags");
const getUnpublishedPackages = require("./lib/get-unpublished-packages");
const getNpmUsername = require("./lib/get-npm-username");
const getTaggedPackages = require("./lib/get-tagged-packages");
const getPackagesWithoutLicense = require("./lib/get-packages-without-license");
const gitCheckout = require("./lib/git-checkout");
const removeTempLicenses = require("./lib/remove-temp-licenses");
const verifyNpmPackageAccess = require("./lib/verify-npm-package-access");

module.exports = factory;

function factory(argv) {
  return new PublishCommand(argv);
}

class PublishCommand extends Command {
  get otherCommandConfigs() {
    // back-compat
    return ["version"];
  }

  initialize() {
    if (this.options.skipNpm) {
      // TODO: remove in next major release
      this.logger.warn("deprecated", "Instead of --skip-npm, call `lerna version` directly");

      return versionCommand(this.argv).then(() => false);
    }

    if (this.options.canary) {
      this.logger.info("canary", "enabled");
    }

    if (this.options.requireScripts) {
      this.logger.info("require-scripts", "enabled");
    }

    // inverted boolean options
    this.verifyAccess = this.options.verifyAccess !== false;

    // https://docs.npmjs.com/misc/config#save-prefix
    this.savePrefix = this.options.exact ? "" : "^";

    // npmSession and user-agent are consumed by libnpm/fetch (via libnpm/publish)
    const npmSession = crypto.randomBytes(8).toString("hex");
    const userAgent = `lerna/${this.options.lernaVersion}/node@${process.version}+${process.arch} (${
      process.platform
    })`;

    this.logger.verbose("session", npmSession);
    this.logger.verbose("user-agent", userAgent);

    this.conf = npmConf({
      lernaCommand: "publish",
      npmSession,
      npmVersion: userAgent,
      registry: this.options.registry,
    });

    this.conf.set("user-agent", userAgent, "cli");

    if (this.conf.get("registry") === "https://registry.yarnpkg.com") {
      this.logger.warn("", "Yarn's registry proxy is broken, replacing with public npm registry");
      this.logger.warn("", "If you don't have an npm token, you should exit and run `npm login`");

      this.conf.set("registry", "https://registry.npmjs.org/", "cli");
    }

    // inject --npm-tag into opts, if present
    const distTag = this.getDistTag();

    if (distTag) {
      this.conf.set("tag", distTag.trim(), "cli");
    }

    // all consumers need a token
    const registry = this.conf.get("registry");
    const auth = getAuth(registry, this.conf.snapshot);

    if (auth.token) {
      this.conf.set("token", auth.token, "cli");
    }

    let chain = Promise.resolve();

    // validate user has valid npm credentials first,
    // by far the most common form of failed execution
    chain = chain.then(() => getNpmUsername(this.conf.snapshot));
    chain = chain.then(username => {
      // username is necessary for subsequent access check
      this.conf.add({ username }, "cmd");
    });
    chain = chain.then(() => this.findVersionedUpdates());

    return chain.then(result => {
      if (!result) {
        // early return from nested VersionCommand
        return false;
      }

      if (!result.updates.length) {
        this.logger.success("No changed packages to publish");

        // still exits zero, aka "ok"
        return false;
      }

      this.updates = result.updates;
      this.updatesVersions = new Map(result.updatesVersions);

      this.runPackageLifecycle = createRunner(this.options);
      this.packagesToPublish = this.updates.map(({ pkg }) => pkg).filter(pkg => !pkg.private);
      this.batchedPackages = this.toposort
        ? batchPackages(
            this.packagesToPublish,
            this.options.rejectCycles,
            // Don't sort based on devDependencies because that
            // would increase the chance of dependency cycles
            // causing less-than-ideal a publishing order.
            "dependencies"
          )
        : [this.packagesToPublish];

      if (result.needsConfirmation) {
        // only confirm for --canary, bump === "from-git",
        // or bump === "from-package", as VersionCommand
        // has its own confirmation prompt
        return this.confirmPublish();
      }

      return true;
    });
  }

  execute() {
    this.enableProgressBar();
    this.logger.info("publish", "Publishing packages to npm...");

    let chain = Promise.resolve();

    chain = chain.then(() => this.prepareRegistryActions());
    chain = chain.then(() => this.prepareLicenseActions());

    if (this.options.canary) {
      chain = chain.then(() => this.updateCanaryVersions());
    }

    chain = chain.then(() => this.resolveLocalDependencyLinks());
    chain = chain.then(() => this.annotateGitHead());
    chain = chain.then(() => this.serializeChanges());
    chain = chain.then(() => this.packUpdated());
    chain = chain.then(() => this.publishPacked());

    if (this.options.gitReset !== false) {
      chain = chain.then(() => this.resetChanges());
    }

    if (this.options.tempTag) {
      chain = chain.then(() => this.npmUpdateAsLatest());
    }

    return chain.then(() => {
      const count = this.packagesToPublish.length;
      const message = this.packagesToPublish.map(pkg => ` - ${pkg.name}@${pkg.version}`);

      output("Successfully published:");
      output(message.join(os.EOL));

      this.logger.success("published", "%d %s", count, count === 1 ? "package" : "packages");
    });
  }

  findVersionedUpdates() {
    let chain = Promise.resolve();

    if (this.options.bump === "from-git") {
      chain = chain.then(() => this.detectFromGit());
    } else if (this.options.bump === "from-package") {
      chain = chain.then(() => this.detectFromPackage());
    } else if (this.options.canary) {
      chain = chain.then(() => this.detectCanaryVersions());
    } else {
      chain = chain.then(() => versionCommand(this.argv));
    }

    return chain;
  }

  verifyWorkingTreeClean() {
    return describeRef(this.execOpts).then(checkWorkingTree.throwIfUncommitted);
  }

  detectFromGit() {
    const { tagVersionPrefix = "v" } = this.options;
    const matchingPattern = this.project.isIndependent() ? "*@*" : `${tagVersionPrefix}*.*.*`;

    let chain = Promise.resolve();

    // attempting to publish a tagged release with local changes is not allowed
    chain = chain.then(() => this.verifyWorkingTreeClean());

    chain = chain.then(() => getCurrentTags(this.execOpts, matchingPattern));
    chain = chain.then(taggedPackageNames => {
      if (!taggedPackageNames.length) {
        this.logger.notice("from-git", "No tagged release found");

        return [];
      }

      if (this.project.isIndependent()) {
        return taggedPackageNames.map(name => this.packageGraph.get(name));
      }

      return getTaggedPackages(this.packageGraph, this.project.rootPath, this.execOpts);
    });

    return chain.then(updates => {
      const updatesVersions = updates.map(({ pkg }) => [pkg.name, pkg.version]);

      return {
        updates,
        updatesVersions,
        needsConfirmation: true,
      };
    });
  }

  detectFromPackage() {
    let chain = Promise.resolve();

    // attempting to publish a release with local changes is not allowed
    chain = chain.then(() => this.verifyWorkingTreeClean());

    chain = chain.then(() => getUnpublishedPackages(this.project, this.conf.snapshot));
    chain = chain.then(unpublishedPackages => {
      if (!unpublishedPackages.length) {
        this.logger.notice("from-package", "No unpublished release found");
      }

      return unpublishedPackages.map(({ name }) => this.packageGraph.get(name));
    });

    return chain.then(updates => {
      const updatesVersions = updates.map(({ pkg }) => [pkg.name, pkg.version]);

      return {
        updates,
        updatesVersions,
        needsConfirmation: true,
      };
    });
  }

  detectCanaryVersions() {
    const {
      bump = "prepatch",
      preid = "alpha",
      tagVersionPrefix = "v",
      ignoreChanges,
      forcePublish,
      includeMergedTags,
    } = this.options;
    // "prerelease" and "prepatch" are identical, for our purposes
    const release = bump.startsWith("pre") ? bump.replace("release", "patch") : `pre${bump}`;

    let chain = Promise.resolve();

    // attempting to publish a canary release with local changes is not allowed
    chain = chain.then(() => this.verifyWorkingTreeClean());

    // find changed packages since last release, if any
    chain = chain.then(() =>
      collectUpdates(this.packageGraph.rawPackageList, this.packageGraph, this.execOpts, {
        bump: "prerelease",
        canary: true,
        ignoreChanges,
        forcePublish,
        includeMergedTags,
      })
    );

    const makeVersion = ({ lastVersion, refCount, sha }) => {
      // the next version is bumped without concern for preid or current index
      const nextVersion = semver.inc(lastVersion, release.replace("pre", ""));

      // semver.inc() starts a new prerelease at .0, git describe starts at .1
      // and build metadata is always ignored when comparing dependency ranges
      return `${nextVersion}-${preid}.${Math.max(0, refCount - 1)}+${sha}`;
    };

    if (this.project.isIndependent()) {
      // each package is described against its tags only
      chain = chain.then(updates =>
        pMap(updates, ({ pkg }) =>
          describeRef({
            match: `${pkg.name}@*`,
            cwd: this.execOpts.cwd,
            includeMergedTags,
          })
            .then(({ lastVersion = pkg.version, refCount, sha }) =>
              // an unpublished package will have no reachable git tag
              makeVersion({ lastVersion, refCount, sha })
            )
            .then(version => [pkg.name, version])
        ).then(updatesVersions => ({
          updates,
          updatesVersions,
        }))
      );
    } else {
      // all packages are described against the last tag
      chain = chain.then(updates =>
        describeRef({
          match: `${tagVersionPrefix}*.*.*`,
          cwd: this.execOpts.cwd,
          includeMergedTags,
        })
          .then(makeVersion)
          .then(version => updates.map(({ pkg }) => [pkg.name, version]))
          .then(updatesVersions => ({
            updates,
            updatesVersions,
          }))
      );
    }

    return chain.then(({ updates, updatesVersions }) => ({
      updates,
      updatesVersions,
      needsConfirmation: true,
    }));
  }

  confirmPublish() {
    const count = this.packagesToPublish.length;
    const message = this.packagesToPublish.map(
      pkg => ` - ${pkg.name} => ${this.updatesVersions.get(pkg.name)}`
    );

    output("");
    output(`Found ${count} ${count === 1 ? "package" : "packages"} to publish:`);
    output(message.join(os.EOL));
    output("");

    if (this.options.yes) {
      this.logger.info("auto-confirmed");
      return true;
    }

    return PromptUtilities.confirm("Are you sure you want to publish these packages?");
  }

  prepareLicenseActions() {
    return Promise.resolve()
      .then(() => getPackagesWithoutLicense(this.project, this.packagesToPublish))
      .then(packagesWithoutLicense => {
        if (packagesWithoutLicense.length && !this.project.licensePath) {
          this.packagesToBeLicensed = [];
          this.logger.warn(
            "ENOLICENSE",
            `Packages ${packagesWithoutLicense.map(pkg => pkg.name).join(", ")} are missing a license`
          );
        } else {
          this.packagesToBeLicensed = packagesWithoutLicense;
        }
      });
  }

  prepareRegistryActions() {
    let chain = Promise.resolve();

    /* istanbul ignore if */
    if (process.env.LERNA_INTEGRATION) {
      return chain;
    }

    // if no username was retrieved, don't bother validating
    if (this.conf.get("username") && this.verifyAccess) {
      chain = chain.then(() => verifyNpmPackageAccess(this.packagesToPublish, this.conf.snapshot));
    }

    return chain;
  }

  updateCanaryVersions() {
    const publishableUpdates = this.updates.filter(node => !node.pkg.private);

    return pMap(publishableUpdates, ({ pkg, localDependencies }) => {
      pkg.version = this.updatesVersions.get(pkg.name);

      for (const [depName, resolved] of localDependencies) {
        // other canary versions need to be updated, non-canary is a no-op
        const depVersion = this.updatesVersions.get(depName) || this.packageGraph.get(depName).pkg.version;

        // it no longer matters if we mutate the shared Package instance
        pkg.updateLocalDependency(resolved, depVersion, this.savePrefix);
      }

      // writing changes to disk handled in serializeChanges()
    });
  }

  resolveLocalDependencyLinks() {
    // resolve relative file: links to their actual version range
    const updatesWithLocalLinks = this.updates.filter(
      ({ pkg, localDependencies }) =>
        !pkg.private &&
        localDependencies.size &&
        Array.from(localDependencies.values()).some(({ type }) => type === "directory")
    );

    return pMap(updatesWithLocalLinks, ({ pkg, localDependencies }) => {
      for (const [depName, resolved] of localDependencies) {
        // regardless of where the version comes from, we can't publish "file:../sibling-pkg" specs
        const depVersion = this.updatesVersions.get(depName) || this.packageGraph.get(depName).pkg.version;

        // it no longer matters if we mutate the shared Package instance
        pkg.updateLocalDependency(resolved, depVersion, this.savePrefix);
      }

      // writing changes to disk handled in serializeChanges()
    });
  }

  annotateGitHead() {
    const gitHead = getCurrentSHA(this.execOpts);

    for (const pkg of this.packagesToPublish) {
      // provide gitHead property that is normally added during npm publish
      pkg.set("gitHead", gitHead);
    }

    // writing changes to disk handled in serializeChanges()
  }

  serializeChanges() {
    return pMap(this.packagesToPublish, pkg => pkg.serialize());
  }

  resetChanges() {
    // the package.json files are changed (by gitHead if not --canary)
    // and we should always leave the working tree clean
    const { cwd } = this.execOpts;
    const dirtyManifests = [this.project.manifest]
      .concat(this.packagesToPublish)
      .map(pkg => path.relative(cwd, pkg.manifestLocation));

    return gitCheckout(dirtyManifests, this.execOpts);
  }

  execScript(pkg, script) {
    const scriptLocation = path.join(pkg.location, "scripts", script);

    try {
      // eslint-disable-next-line import/no-dynamic-require, global-require
      require(scriptLocation);
    } catch (ex) {
      this.logger.silly("execScript", `No ${script} script found at ${scriptLocation}`);
    }

    return pkg;
  }

  removeTempLicensesOnError(error) {
    return Promise.resolve()
      .then(() =>
        removeTempLicenses(this.packagesToBeLicensed).catch(removeError => {
          this.logger.error(
            "licenses",
            "error removing temporary license files",
            removeError.stack || removeError
          );
        })
      )
      .then(() => {
        // restore original error into promise chain
        throw error;
      });
  }

  packUpdated() {
    const tracker = this.logger.newItem("npm pack");

    tracker.addWork(this.packagesToPublish.length + 1);

    let chain = Promise.resolve();

    chain = chain.then(() => createTempLicenses(this.project.licensePath, this.packagesToBeLicensed));

    chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "prepare"));
    chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "prepublishOnly"));
    chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "prepack"));

    const { contents } = this.options;
    const getLocation = contents ? pkg => path.resolve(pkg.location, contents) : pkg => pkg.location;

    const opts = this.conf.snapshot;
    const mapper = pPipe(
      [
        this.options.requireScripts && (pkg => this.execScript(pkg, "prepublish")),

        pkg =>
          pulseTillDone(packDirectory(pkg, getLocation(pkg), opts)).then(packed => {
            tracker.completeWork(1);

            // store metadata for use in this.publishPacked()
            pkg.packed = packed;

            // manifest may be mutated by any previous lifecycle
            return pkg.refresh();
          }),
      ].filter(Boolean)
    );

    chain = chain.then(() =>
      pReduce(this.batchedPackages, (_, batch) => pMap(batch, mapper, { concurrency: 10 }))
    );

    chain = chain.then(() => removeTempLicenses(this.packagesToBeLicensed));

    // remove temporary license files if _any_ error occurs _anywhere_ in the promise chain
    chain = chain.catch(error => this.removeTempLicensesOnError(error));

    chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "postpack"));

    return pFinally(chain, () => tracker.finish());
  }

  publishPacked() {
    // if we skip temp tags we should tag with the proper value immediately
    const distTag = this.options.tempTag ? "lerna-temp" : this.conf.get("tag");
    const tracker = this.logger.newItem("publish");

    tracker.addWork(this.packagesToPublish.length);

    let chain = Promise.resolve();

    const opts = this.conf.snapshot;
    const mapper = pPipe(
      [
        pkg =>
          pulseTillDone(npmPublish(pkg, distTag, pkg.packed.tarFilePath, opts)).then(() => {
            tracker.completeWork(1);
            tracker.success("published", pkg.name, pkg.version);

            logPacked(pkg.packed);

            return pkg;
          }),

        this.options.requireScripts && (pkg => this.execScript(pkg, "postpublish")),
      ].filter(Boolean)
    );

    chain = chain.then(() => runParallelBatches(this.batchedPackages, this.concurrency, mapper));

    // we do not run root "publish" lifecycle because it has a great chance of being cyclical
    chain = chain.then(() => this.runPackageLifecycle(this.project.manifest, "postpublish"));

    return pFinally(chain, () => tracker.finish());
  }

  npmUpdateAsLatest() {
    const distTag = this.conf.get("tag");
    const tracker = this.logger.newItem("npmUpdateAsLatest");

    tracker.addWork(this.packagesToPublish.length);
    tracker.showProgress();

    let chain = Promise.resolve();

    const opts = this.conf.snapshot;
    const mapper = pkg => {
      const spec = `${pkg.name}@${pkg.version}`;

      return Promise.resolve()
        .then(() => pulseTillDone(npmDistTag.remove(spec, "lerna-temp", opts)))
        .then(() => pulseTillDone(npmDistTag.add(spec, distTag, opts)))
        .then(() => {
          tracker.success("dist-tag", "%s@%s => %j", pkg.name, pkg.version, distTag);
          tracker.completeWork(1);

          return pkg;
        });
    };

    chain = chain.then(() => runParallelBatches(this.batchedPackages, this.concurrency, mapper));

    return pFinally(chain, () => tracker.finish());
  }

  getDistTag() {
    if (this.options.npmTag) {
      return this.options.npmTag;
    }

    if (this.options.canary) {
      return "canary";
    }

    // undefined defaults to "latest" OR whatever is in pkg.publishConfig.tag
  }
}

module.exports.PublishCommand = PublishCommand;


# `@lerna/has-npm-version`

> Test if the current version of npm satisfies a given semver range

## Usage

```js
const hasNpmVersion = require("@lerna/has-npm-version");

// `npm --version` === 6.3.0
hasNpmVersion(">=6"); // => true

// `npm --version` === 5.6.0
hasNpmVersion(">=6"); // => false

// makePredicate() caches the call to `npm --version`
// useful if you're calling it repeatedly in a loop
const predicate = hasNpmVersion.makePredicate();

// `npm --version` === 6.3.0
hasNpmVersion(">=5"); // => true
```


// emit all buffered logs at configured level and higher

keep keep keep keep keep replace replace replace replace replace replace replace keep keep keep keep keep


@lerna/collect-updates

An internal Lerna tool


"use strict";

const Package = require("@lerna/package");

// file under test
const PackageGraph = require("..");

describe("PackageGraph", () => {
  describe("Node", () => {
    it("proxies Package properties", () => {
      const pkg = new Package({ name: "my-pkg", version: "1.2.3" }, "/path/to/my-pkg");
      const graph = new PackageGraph([pkg]);
      const node = graph.get("my-pkg");

      // most of these properties are non-enumerable, so a snapshot doesn't work
      expect(node.name).toBe("my-pkg");
      expect(node.location).toBe("/path/to/my-pkg");
      expect(node.prereleaseId).toBeUndefined();
      expect(node.version).toBe("1.2.3");
      expect(node.pkg).toBe(pkg);
    });

    it("exposes graph-specific Map properties", () => {
      const node = new PackageGraph([
        new Package({ name: "my-pkg", version: "4.5.6" }, "/path/to/my-pkg"),
      ]).get("my-pkg");

      expect(node).toHaveProperty("externalDependencies", expect.any(Map));
      expect(node).toHaveProperty("localDependencies", expect.any(Map));
      expect(node).toHaveProperty("localDependents", expect.any(Map));
    });

    it("computes prereleaseId from prerelease version", () => {
      const node = new PackageGraph([
        new Package({ name: "my-pkg", version: "1.2.3-rc.4" }, "/path/to/my-pkg"),
      ]).get("my-pkg");

      expect(node.prereleaseId).toBe("rc");
    });
  });

  describe(".get()", () => {
    it("should return a node with localDependencies", () => {
      const packages = [
        new Package(
          {
            name: "my-package-1",
            version: "1.0.0",
            dependencies: {
              "external-thing": "^1.0.0",
            },
          },
          "/path/to/package-1"
        ),
        new Package(
          {
            name: "my-package-2",
            version: "1.0.0",
            devDependencies: {
              "my-package-1": "^1.0.0",
            },
          },
          "/path/to/package-2"
        ),
      ];
      const graph = new PackageGraph(packages, "allDependencies");

      expect(graph.get("my-package-1").localDependencies.size).toBe(0);
      expect(graph.get("my-package-2").localDependencies.has("my-package-1")).toBe(true);
    });

    it("should skip gitCommittish of packages that are not in localDependencies", () => {
      const packages = [
        new Package(
          {
            name: "my-package-1",
            version: "1.0.0",
            devDependencies: {
              "my-package-2": "^1.0.0",
            },
          },
          "/path/to/package-1"
        ),
        new Package(
          {
            name: "my-package-2",
            version: "1.0.0",
            dependencies: {
              "external-thing": "github:user-foo/project-foo#v1.0.0",
            },
          },
          "/path/to/package-2"
        ),
      ];
      const graph = new PackageGraph(packages, "dependencies");

      expect(graph.get("my-package-1").localDependencies.size).toBe(0);
      expect(graph.get("my-package-2").localDependencies.size).toBe(0);
    });

    it("should return the localDependencies for matched gitCommittish", () => {
      const packages = [
        new Package(
          {
            name: "my-package-1",
            version: "1.0.0",
            dependencies: {
              "external-thing": "^1.0.0",
            },
          },
          "/path/to/package-1"
        ),
        new Package(
          {
            name: "my-package-2",
            version: "1.0.0",
            devDependencies: {
              "my-package-1": "github:user-foo/project-foo#v1.0.0",
            },
          },
          "/path/to/package-2"
        ),
      ];
      const graph = new PackageGraph(packages);

      expect(graph.get("my-package-2").localDependencies.has("my-package-1")).toBe(true);
    });
  });
});


<template>
	<n8n-input-label
		:label="hideLabel ? '' : $locale.nodeText().inputLabelDisplayName(parameter, path)"
		:tooltipText="hideLabel ? '' : $locale.nodeText().inputLabelDescription(parameter, path)"
		:showTooltip="focused"
		:showOptions="menuExpanded || focused || forceShowExpression"
		:bold="false"
		size="small"
		color="text-dark"
	>
		<template #options>
			<parameter-options
				:parameter="parameter"
				:value="value"
				:isReadOnly="isReadOnly"
				:showOptions="displayOptions"
				:showExpressionSelector="showExpressionSelector"
				@optionSelected="optionSelected"
				@menu-expanded="onMenuExpanded"
			/>
		</template>
		<template>
			<draggable-target
				type="mapping"
				:disabled="isDropDisabled"
				:sticky="true"
				:stickyOffset="isValueExpression ? [26, 3] : [3, 3]"
				@drop="onDrop"
			>
				<template #default="{ droppable, activeDrop }">
					<n8n-tooltip
						placement="left"
						:manual="true"
						:value="showMappingTooltip"
						:buttons="dataMappingTooltipButtons"
					>
						<template #content>
							<span
								v-html="
									$locale.baseText(`dataMapping.${displayMode}Hint`, {
										interpolate: { name: parameter.displayName },
									})
								"
							/>
						</template>
						<parameter-input-wrapper
							ref="param"
							:parameter="parameter"
							:value="value"
							:path="path"
							:isReadOnly="isReadOnly"
							:droppable="droppable"
							:activeDrop="activeDrop"
							:forceShowExpression="forceShowExpression"
							:hint="hint"
							:hide-issues="hideIssues"
							@valueChanged="valueChanged"
							@textInput="onTextInput"
							@focus="onFocus"
							@blur="onBlur"
							@drop="onDrop"
							inputSize="small"
						/>
					</n8n-tooltip>
				</template>
			</draggable-target>
		</template>
	</n8n-input-label>
</template>

<script lang="ts">
import Vue, { PropType } from 'vue';

import { IN8nButton, INodeUi, IRunDataDisplayMode, IUpdateInformation } from '@/Interface';

import ParameterOptions from '@/components/ParameterOptions.vue';
import DraggableTarget from '@/components/DraggableTarget.vue';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import { LOCAL_STORAGE_MAPPING_FLAG } from '@/constants';
import {
	hasExpressionMapping,
	isResourceLocatorValue,
	hasOnlyListMode,
	isValueExpression,
} from '@/utils';
import ParameterInputWrapper from '@/components/ParameterInputWrapper.vue';
import { INodeParameters, INodeProperties, INodePropertyMode } from 'n8n-workflow';
import { BaseTextKey } from '@/plugins/i18n';
import { mapStores } from 'pinia';
import { useNDVStore } from '@/stores/ndv';

export default mixins(showMessage).extend({
	name: 'parameter-input-full',
	components: {
		ParameterOptions,
		DraggableTarget,
		ParameterInputWrapper,
	},
	data() {
		return {
			focused: false,
			menuExpanded: false,
			forceShowExpression: false,
			dataMappingTooltipButtons: [] as IN8nButton[],
			mappingTooltipEnabled: false,
			localStorageMappingFlag: window.localStorage.getItem(LOCAL_STORAGE_MAPPING_FLAG) === 'true',
		};
	},
	props: {
		displayOptions: {
			type: Boolean,
			default: false,
		},
		isReadOnly: {
			type: Boolean,
			default: false,
		},
		hideLabel: {
			type: Boolean,
			default: false,
		},
		hideIssues: {
			type: Boolean,
			default: false,
		},
		parameter: {
			type: Object as PropType<INodeProperties>,
		},
		path: {
			type: String,
		},
		value: {
			type: [Number, String, Boolean, Array, Object] as PropType<INodeParameters>,
		},
	},
	created() {
		const mappingTooltipDismissHandler = this.onMappingTooltipDismissed.bind(this);
		this.dataMappingTooltipButtons = [
			{
				attrs: {
					label: this.$locale.baseText('_reusableBaseText.dismiss' as BaseTextKey),
				},
				listeners: {
					click: mappingTooltipDismissHandler,
				},
			},
		];
	},
	computed: {
		...mapStores(useNDVStore),
		node(): INodeUi | null {
			return this.ndvStore.activeNode;
		},
		hint(): string | null {
			return this.$locale.nodeText().hint(this.parameter, this.path);
		},
		isInputTypeString(): boolean {
			return this.parameter.type === 'string';
		},
		isResourceLocator(): boolean {
			return this.parameter.type === 'resourceLocator';
		},
		isDropDisabled(): boolean {
			return this.parameter.noDataExpression || this.isReadOnly || this.isResourceLocator;
		},
		isValueExpression(): boolean {
			return isValueExpression(this.parameter, this.value);
		},
		showExpressionSelector(): boolean {
			return this.isResourceLocator ? !hasOnlyListMode(this.parameter) : true;
		},
		isInputDataEmpty(): boolean {
			return this.ndvStore.isDNVDataEmpty('input');
		},
		displayMode(): IRunDataDisplayMode {
			return this.ndvStore.inputPanelDisplayMode;
		},
		showMappingTooltip(): boolean {
			return (
				this.mappingTooltipEnabled &&
				this.focused &&
				this.isInputTypeString &&
				!this.isInputDataEmpty &&
				!this.localStorageMappingFlag
			);
		},
	},
	methods: {
		onFocus() {
			this.focused = true;
			setTimeout(() => {
				this.mappingTooltipEnabled = true;
			}, 500);
			if (!this.parameter.noDataExpression) {
				this.ndvStore.setMappableNDVInputFocus(this.parameter.displayName);
			}
		},
		onBlur() {
			this.focused = false;
			this.mappingTooltipEnabled = false;
			if (!this.parameter.noDataExpression) {
				this.ndvStore.setMappableNDVInputFocus('');
			}
			this.$emit('blur');
		},
		onMenuExpanded(expanded: boolean) {
			this.menuExpanded = expanded;
		},
		optionSelected(command: string) {
			if (this.$refs.param) {
				(this.$refs.param as Vue).$emit('optionSelected', command);
			}
		},
		valueChanged(parameterData: IUpdateInformation) {
			this.$emit('valueChanged', parameterData);
		},
		onTextInput(parameterData: IUpdateInformation) {
			const param = this.$refs.param as Vue | undefined;

			if (isValueExpression(this.parameter, parameterData.value)) {
				param?.$emit('optionSelected', 'addExpression');
			}
		},
		onDrop(data: string) {
			this.forceShowExpression = true;
			setTimeout(() => {
				if (this.node) {
					const prevValue = this.isResourceLocator ? this.value.value : this.value;
					let updatedValue: string;
					if (typeof prevValue === 'string' && prevValue.startsWith('=') && prevValue.length > 1) {
						updatedValue = `${prevValue} ${data}`;
					} else {
						updatedValue = `=${data}`;
					}

					let parameterData;
					if (this.isResourceLocator) {
						if (!isResourceLocatorValue(this.value)) {
							parameterData = {
								node: this.node.name,
								name: this.path,
								value: { __rl: true, value: updatedValue, mode: '' },
							};
						} else if (
							this.value.mode === 'list' &&
							this.parameter.modes &&
							this.parameter.modes.length > 1
						) {
							let mode =
								this.parameter.modes.find((mode: INodePropertyMode) => mode.name === 'id') || null;
							if (!mode) {
								mode = this.parameter.modes.filter(
									(mode: INodePropertyMode) => mode.name !== 'list',
								)[0];
							}

							parameterData = {
								node: this.node.name,
								name: this.path,
								value: { __rl: true, value: updatedValue, mode: mode ? mode.name : '' },
							};
						} else {
							parameterData = {
								node: this.node.name,
								name: this.path,
								value: { __rl: true, value: updatedValue, mode: this.value.mode },
							};
						}
					} else {
						parameterData = {
							node: this.node.name,
							name: this.path,
							value: updatedValue,
						};
					}

					this.$emit('valueChanged', parameterData);

					if (window.localStorage.getItem(LOCAL_STORAGE_MAPPING_FLAG) !== 'true') {
						this.$showMessage({
							title: this.$locale.baseText('dataMapping.success.title'),
							message: this.$locale.baseText('dataMapping.success.moreInfo'),
							type: 'success',
						});

						window.localStorage.setItem(LOCAL_STORAGE_MAPPING_FLAG, 'true');
					}

					this.ndvStore.setMappingTelemetry({
						dest_node_type: this.node.type,
						dest_parameter: this.path,
						dest_parameter_mode:
							typeof prevValue === 'string' && prevValue.startsWith('=') ? 'expression' : 'fixed',
						dest_parameter_empty: prevValue === '' || prevValue === undefined,
						dest_parameter_had_mapping:
							typeof prevValue === 'string' &&
							prevValue.startsWith('=') &&
							hasExpressionMapping(prevValue),
						success: true,
					});
				}
				this.forceShowExpression = false;
			}, 200);
		},
		onMappingTooltipDismissed() {
			window.localStorage.setItem(LOCAL_STORAGE_MAPPING_FLAG, 'true');
			this.localStorageMappingFlag = true;
		},
	},
	watch: {
		showMappingTooltip(newValue: boolean) {
			if (!newValue) {
				this.$telemetry.track('User viewed data mapping tooltip', { type: 'param focus' });
			}
		},
	},
});
</script>


export * from './OrganizationDescription';
export * from './SpaceDescription';
export * from './UserDescription';
export * from './WorkItemDescription';