-
+
{t('exit_confirmation_body')}
diff --git a/opentrons-ai-client/src/molecules/FeedbackModal/__tests__/FeedbackModal.test.tsx b/opentrons-ai-client/src/molecules/FeedbackModal/__tests__/FeedbackModal.test.tsx
index 15d17938e93..2d881633822 100644
--- a/opentrons-ai-client/src/molecules/FeedbackModal/__tests__/FeedbackModal.test.tsx
+++ b/opentrons-ai-client/src/molecules/FeedbackModal/__tests__/FeedbackModal.test.tsx
@@ -1,10 +1,20 @@
import { FeedbackModal } from '..'
import { renderWithProviders } from '../../../__testing-utils__'
-import { screen } from '@testing-library/react'
-import { describe, it, expect } from 'vitest'
+import { fireEvent, screen, waitFor } from '@testing-library/react'
+import { describe, it, expect, vi } from 'vitest'
import { i18n } from '../../../i18n'
import { feedbackModalAtom } from '../../../resources/atoms'
+const mockUseTrackEvent = vi.fn()
+
+vi.mock('../../../resources/hooks/useTrackEvent', () => ({
+ useTrackEvent: () => mockUseTrackEvent,
+}))
+
+vi.mock('../../../hooks/useTrackEvent', () => ({
+ useTrackEvent: () => mockUseTrackEvent,
+}))
+
const initialValues: Array<[any, any]> = [[feedbackModalAtom, true]]
const render = (): ReturnType => {
@@ -33,4 +43,26 @@ describe('FeedbackModal', () => {
// check if the feedbackModalAtom is set to false
expect(feedbackModalAtom.read).toBe(false)
})
+
+ it('should track event when feedback is sent', async () => {
+ render()
+ const feedbackInput = screen.getByRole('textbox')
+ fireEvent.change(feedbackInput, {
+ target: { value: 'This is a test feedback' },
+ })
+ const sendFeedbackButton = screen.getByRole('button', {
+ name: 'Send feedback',
+ })
+
+ fireEvent.click(sendFeedbackButton)
+
+ await waitFor(() => {
+ expect(mockUseTrackEvent).toHaveBeenCalledWith({
+ name: 'feedback-sent',
+ properties: {
+ feedback: 'This is a test feedback',
+ },
+ })
+ })
+ })
})
diff --git a/opentrons-ai-client/src/molecules/FeedbackModal/index.tsx b/opentrons-ai-client/src/molecules/FeedbackModal/index.tsx
index fbb006bdbd4..017048910b8 100644
--- a/opentrons-ai-client/src/molecules/FeedbackModal/index.tsx
+++ b/opentrons-ai-client/src/molecules/FeedbackModal/index.tsx
@@ -19,9 +19,11 @@ import {
LOCAL_FEEDBACK_END_POINT,
} from '../../resources/constants'
import { useApiCall } from '../../resources/hooks'
+import { useTrackEvent } from '../../resources/hooks/useTrackEvent'
export function FeedbackModal(): JSX.Element {
const { t } = useTranslation('protocol_generator')
+ const trackEvent = useTrackEvent()
const [feedbackValue, setFeedbackValue] = useState('')
const [, setShowFeedbackModal] = useAtom(feedbackModalAtom)
@@ -58,6 +60,12 @@ export function FeedbackModal(): JSX.Element {
},
}
await callApi(config as AxiosRequestConfig)
+ trackEvent({
+ name: 'feedback-sent',
+ properties: {
+ feedback: feedbackValue,
+ },
+ })
setShowFeedbackModal(false)
} catch (err: any) {
console.error(`error: ${err.message}`)
diff --git a/opentrons-ai-client/src/molecules/InputPrompt/__tests__/InputPrompt.test.tsx b/opentrons-ai-client/src/molecules/InputPrompt/__tests__/InputPrompt.test.tsx
index f6f588aeab7..3f704a39dda 100644
--- a/opentrons-ai-client/src/molecules/InputPrompt/__tests__/InputPrompt.test.tsx
+++ b/opentrons-ai-client/src/molecules/InputPrompt/__tests__/InputPrompt.test.tsx
@@ -1,11 +1,21 @@
import type * as React from 'react'
-import { describe, it, expect } from 'vitest'
+import { describe, it, expect, vi } from 'vitest'
import { FormProvider, useForm } from 'react-hook-form'
-import { fireEvent, screen } from '@testing-library/react'
+import { fireEvent, screen, waitFor } from '@testing-library/react'
import { renderWithProviders } from '../../../__testing-utils__'
import { i18n } from '../../../i18n'
import { InputPrompt } from '../index'
+const mockUseTrackEvent = vi.fn()
+
+vi.mock('../../../resources/hooks/useTrackEvent', () => ({
+ useTrackEvent: () => mockUseTrackEvent,
+}))
+
+vi.mock('../../../hooks/useTrackEvent', () => ({
+ useTrackEvent: () => mockUseTrackEvent,
+}))
+
const WrappingForm = (wrappedComponent: {
children: React.ReactNode
}): JSX.Element => {
@@ -44,4 +54,21 @@ describe('InputPrompt', () => {
})
// ToDo (kk:04/19/2024) add more test cases
+
+ it('should track event when send button is clicked', async () => {
+ render()
+ const textbox = screen.getByRole('textbox')
+ fireEvent.change(textbox, { target: { value: ['test'] } })
+ const sendButton = screen.getByRole('button')
+ fireEvent.click(sendButton)
+
+ await waitFor(() => {
+ expect(mockUseTrackEvent).toHaveBeenCalledWith({
+ name: 'chat-submitted',
+ properties: {
+ chat: 'test',
+ },
+ })
+ })
+ })
})
diff --git a/opentrons-ai-client/src/molecules/InputPrompt/index.tsx b/opentrons-ai-client/src/molecules/InputPrompt/index.tsx
index 56114535733..e90ba453ab9 100644
--- a/opentrons-ai-client/src/molecules/InputPrompt/index.tsx
+++ b/opentrons-ai-client/src/molecules/InputPrompt/index.tsx
@@ -20,6 +20,7 @@ import {
chatDataAtom,
chatHistoryAtom,
createProtocolChatAtom,
+ regenerateProtocolAtom,
tokenAtom,
updateProtocolChatAtom,
} from '../../resources/atoms'
@@ -38,11 +39,17 @@ import {
} from '../../resources/constants'
import type { AxiosRequestConfig } from 'axios'
-import type { ChatData } from '../../resources/types'
+import type {
+ ChatData,
+ CreatePrompt,
+ UpdatePrompt,
+} from '../../resources/types'
+import { useTrackEvent } from '../../resources/hooks/useTrackEvent'
export function InputPrompt(): JSX.Element {
const { t } = useTranslation('protocol_generator')
const { register, watch, reset, setValue } = useFormContext()
+ const trackEvent = useTrackEvent()
const [updateProtocol] = useAtom(updateProtocolChatAtom)
const [createProtocol] = useAtom(createProtocolChatAtom)
@@ -50,6 +57,9 @@ export function InputPrompt(): JSX.Element {
const [sendAutoFilledPrompt, setSendAutoFilledPrompt] = useState(
false
)
+ const [regenerateProtocol, setRegenerateProtocol] = useAtom(
+ regenerateProtocolAtom
+ )
const [, setChatData] = useAtom(chatDataAtom)
const [chatHistory, setChatHistory] = useAtom(chatHistoryAtom)
@@ -78,13 +88,24 @@ export function InputPrompt(): JSX.Element {
}
}, [watchUserPrompt])
+ useEffect(() => {
+ if (regenerateProtocol.regenerate) {
+ handleClick(regenerateProtocol.isCreateOrUpdateProtocol, true)
+ setRegenerateProtocol({
+ isCreateOrUpdateProtocol: false,
+ regenerate: false,
+ })
+ }
+ }, [regenerateProtocol])
+
const handleClick = async (
- isUpdateOrCreateRequest: boolean = false
+ isUpdateOrCreateRequest: boolean = false,
+ isRegenerateRequest: boolean = false
): Promise => {
- setRequestId(uuidv4() + getPreFixText(isUpdateOrCreateRequest))
-
+ const newRequestId = uuidv4() + getPreFixText(isUpdateOrCreateRequest)
+ setRequestId(newRequestId)
const userInput: ChatData = {
- requestId,
+ requestId: newRequestId,
role: 'user',
reply: watchUserPrompt,
}
@@ -106,7 +127,7 @@ export function InputPrompt(): JSX.Element {
method: 'POST',
headers,
data: isUpdateOrCreateRequest
- ? getUpdateOrCreatePrompt()
+ ? getUpdateOrCreatePrompt(isRegenerateRequest)
: {
message: watchUserPrompt,
history: chatHistory,
@@ -119,6 +140,12 @@ export function InputPrompt(): JSX.Element {
{ role: 'user', content: watchUserPrompt },
])
await callApi(config as AxiosRequestConfig)
+ trackEvent({
+ name: 'chat-submitted',
+ properties: {
+ chat: watchUserPrompt,
+ },
+ })
setSubmitted(true)
} catch (err: any) {
console.error(`error: ${err.message}`)
@@ -126,7 +153,11 @@ export function InputPrompt(): JSX.Element {
}
}
- const getUpdateOrCreatePrompt = (): any => {
+ const getUpdateOrCreatePrompt = (
+ isRegenerateRequest: boolean
+ ): CreatePrompt | UpdatePrompt => {
+ createProtocol.regenerate = isRegenerateRequest
+ updateProtocol.regenerate = isRegenerateRequest
return isNewProtocol ? createProtocol : updateProtocol
}
@@ -159,6 +190,13 @@ export function InputPrompt(): JSX.Element {
{ role: 'assistant', content: reply },
])
setChatData(chatData => [...chatData, assistantResponse])
+ trackEvent({
+ name: 'generated-protocol',
+ properties: {
+ createOrUpdate: isNewProtocol ? 'create' : 'update',
+ protocol: reply,
+ },
+ })
setSubmitted(false)
}
}, [data, isLoading, submitted])
diff --git a/opentrons-ai-client/src/molecules/ModuleListItemGroup/index.tsx b/opentrons-ai-client/src/molecules/ModuleListItemGroup/index.tsx
index 279c4d2060b..0c570600bd4 100644
--- a/opentrons-ai-client/src/molecules/ModuleListItemGroup/index.tsx
+++ b/opentrons-ai-client/src/molecules/ModuleListItemGroup/index.tsx
@@ -22,7 +22,7 @@ import { Controller, useFormContext } from 'react-hook-form'
import { ModuleDiagram } from '../ModelDiagram'
import { MODULES_FIELD_NAME } from '../../organisms/ModulesSection'
import type { DisplayModules } from '../../organisms/ModulesSection'
-import { getAllDefinitions } from '../../resources/utils'
+import { getOnlyLatestDefs } from '../../resources/utils'
import { useTranslation } from 'react-i18next'
import { useMemo } from 'react'
@@ -70,7 +70,7 @@ export function ModuleListItemGroup(): JSX.Element | null {
const modulesWatch: DisplayModules[] = watch(MODULES_FIELD_NAME) ?? []
const allDefinitionsValues = useMemo(
- () => Object.values(getAllDefinitions()),
+ () => Object.values(getOnlyLatestDefs()),
[]
)
diff --git a/opentrons-ai-client/src/organisms/ApplicationSection/__tests__/ApplicationSection.test.tsx b/opentrons-ai-client/src/organisms/ApplicationSection/__tests__/ApplicationSection.test.tsx
index 50e01fcb66f..477c871b7c5 100644
--- a/opentrons-ai-client/src/organisms/ApplicationSection/__tests__/ApplicationSection.test.tsx
+++ b/opentrons-ai-client/src/organisms/ApplicationSection/__tests__/ApplicationSection.test.tsx
@@ -13,6 +13,8 @@ const TestFormProviderComponent = () => {
return (
+
+ {`form is ${methods.formState.isValid ? 'valid' : 'invalid'}`}
)
}
@@ -33,7 +35,6 @@ describe('ApplicationSection', () => {
expect(
screen.getByText('Describe what you are trying to do')
).toBeInTheDocument()
- expect(screen.getByText('Confirm')).toBeInTheDocument()
})
it('should not render other application dropdown if Other option is not selected', () => {
@@ -54,10 +55,10 @@ describe('ApplicationSection', () => {
expect(screen.getByText('Other application')).toBeInTheDocument()
})
- it('should enable confirm button when all fields are filled', async () => {
+ it('should update the form state to valid when all fields are filled', async () => {
render()
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled()
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
const applicationDropdown = screen.getByText('Select an option')
fireEvent.click(applicationDropdown)
@@ -69,14 +70,13 @@ describe('ApplicationSection', () => {
fireEvent.change(describeInput, { target: { value: 'Test description' } })
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled()
+ expect(screen.getByText('form is valid')).toBeInTheDocument()
})
})
- it('should disable confirm button when all fields are not filled', () => {
+ it('should update the form state to invalid when not all fields are filled', () => {
render()
- const confirmButton = screen.getByRole('button')
- expect(confirmButton).toBeDisabled()
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
})
})
diff --git a/opentrons-ai-client/src/organisms/ApplicationSection/index.tsx b/opentrons-ai-client/src/organisms/ApplicationSection/index.tsx
index 5e3cc523f68..54819e99a3a 100644
--- a/opentrons-ai-client/src/organisms/ApplicationSection/index.tsx
+++ b/opentrons-ai-client/src/organisms/ApplicationSection/index.tsx
@@ -1,19 +1,8 @@
-import {
- DIRECTION_COLUMN,
- DISPLAY_FLEX,
- Flex,
- JUSTIFY_FLEX_END,
- LargeButton,
- SPACING,
-} from '@opentrons/components'
+import { DIRECTION_COLUMN, Flex, SPACING } from '@opentrons/components'
import { useFormContext } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
-import styled from 'styled-components'
import { ControlledDropdownMenu } from '../../atoms/ControlledDropdownMenu'
import { ControlledInputField } from '../../atoms/ControlledInputField'
-import { useAtom } from 'jotai'
-import { createProtocolAtom } from '../../resources/atoms'
-import { APPLICATION_STEP } from '../ProtocolSectionsContainer'
export const BASIC_ALIQUOTING = 'basic_aliquoting'
export const PCR = 'pcr'
@@ -25,11 +14,7 @@ export const APPLICATION_DESCRIBE = 'application.description'
export function ApplicationSection(): JSX.Element | null {
const { t } = useTranslation('create_protocol')
- const {
- watch,
- formState: { isValid },
- } = useFormContext()
- const [{ currentStep }, setCreateProtocolAtom] = useAtom(createProtocolAtom)
+ const { watch } = useFormContext()
const options = [
{ name: t(BASIC_ALIQUOTING), value: BASIC_ALIQUOTING },
@@ -39,16 +24,6 @@ export function ApplicationSection(): JSX.Element | null {
const isOtherSelected = watch(APPLICATION_SCIENTIFIC_APPLICATION) === OTHER
- function handleConfirmButtonClick(): void {
- const step =
- currentStep > APPLICATION_STEP ? currentStep : APPLICATION_STEP + 1
-
- setCreateProtocolAtom({
- currentStep: step,
- focusStep: step,
- })
- }
-
return (
-
-
-
-
)
}
-
-const ButtonContainer = styled.div`
- display: ${DISPLAY_FLEX};
- justify-content: ${JUSTIFY_FLEX_END};
-`
diff --git a/opentrons-ai-client/src/organisms/InstrumentsSection/__tests__/InstrumentsSection.test.tsx b/opentrons-ai-client/src/organisms/InstrumentsSection/__tests__/InstrumentsSection.test.tsx
index 11e6bceaf45..0712ede4757 100644
--- a/opentrons-ai-client/src/organisms/InstrumentsSection/__tests__/InstrumentsSection.test.tsx
+++ b/opentrons-ai-client/src/organisms/InstrumentsSection/__tests__/InstrumentsSection.test.tsx
@@ -13,6 +13,8 @@ const TestFormProviderComponent = () => {
return (
+
+ {`form is ${methods.formState.isValid ? 'valid' : 'invalid'}`}
)
}
@@ -24,7 +26,7 @@ const render = (): ReturnType => {
}
describe('ApplicationSection', () => {
- it('should render robot, pipette, flex gripper radios, mounts dropdowns, and confirm button', async () => {
+ it('should render robot, pipette, flex gripper radios and mounts dropdowns', async () => {
render()
expect(
@@ -40,7 +42,6 @@ describe('ApplicationSection', () => {
expect(
screen.getByText('Do you want to use the Flex Gripper?')
).toBeInTheDocument()
- expect(screen.getByText('Confirm')).toBeInTheDocument()
})
it('should not render left and right mount dropdowns if 96-Channel 1000µL pipette radio is selected', () => {
@@ -80,7 +81,7 @@ describe('ApplicationSection', () => {
render()
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled()
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
})
const leftMount = screen.getAllByText('Choose pipette')[0]
@@ -96,14 +97,14 @@ describe('ApplicationSection', () => {
})
expect(screen.getByText('None')).toBeInTheDocument()
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled()
+ expect(screen.getByText('form is valid')).toBeInTheDocument()
})
it('should not be able to select two pipettes with none value', async () => {
render()
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled()
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
})
const leftMount = screen.getAllByText('Choose pipette')[0]
@@ -115,15 +116,15 @@ describe('ApplicationSection', () => {
fireEvent.click(screen.getAllByText('None')[1])
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled()
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
})
})
- it('should enable confirm button when all fields are filled', async () => {
+ it('should update the form state to valid when all fields are filled', async () => {
render()
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled()
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
})
const leftMount = screen.getAllByText('Choose pipette')[0]
@@ -135,16 +136,7 @@ describe('ApplicationSection', () => {
fireEvent.click(screen.getByText('Flex 8-Channel 50 ÎĽL'))
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled()
- })
- })
-
- it('should disable confirm button when all fields are not filled', async () => {
- render()
-
- const confirmButton = screen.getByRole('button')
- await waitFor(() => {
- expect(confirmButton).not.toBeEnabled()
+ expect(screen.getByText('form is valid')).toBeInTheDocument()
})
})
})
diff --git a/opentrons-ai-client/src/organisms/InstrumentsSection/index.tsx b/opentrons-ai-client/src/organisms/InstrumentsSection/index.tsx
index c56276e1dfa..6f815b45a5d 100644
--- a/opentrons-ai-client/src/organisms/InstrumentsSection/index.tsx
+++ b/opentrons-ai-client/src/organisms/InstrumentsSection/index.tsx
@@ -1,19 +1,13 @@
import {
COLORS,
DIRECTION_COLUMN,
- DISPLAY_FLEX,
Flex,
- JUSTIFY_FLEX_END,
- LargeButton,
SPACING,
StyledText,
} from '@opentrons/components'
import { useFormContext } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
-import { useAtom } from 'jotai'
-import { createProtocolAtom } from '../../resources/atoms'
-import { INSTRUMENTS_STEP } from '../ProtocolSectionsContainer'
import { ControlledDropdownMenu } from '../../atoms/ControlledDropdownMenu'
import { ControlledRadioButtonGroup } from '../../molecules/ControlledRadioButtonGroup'
import { useMemo } from 'react'
@@ -21,7 +15,6 @@ import {
getAllPipetteNames,
getPipetteSpecsV2,
OT2_PIPETTES,
- OT2_ROBOT_TYPE,
OT3_PIPETTES,
} from '@opentrons/shared-data'
@@ -40,11 +33,7 @@ export const NO_PIPETTES = 'none'
export function InstrumentsSection(): JSX.Element | null {
const { t } = useTranslation('create_protocol')
- const {
- formState: { isValid },
- watch,
- } = useFormContext()
- const [{ currentStep }, setCreateProtocolAtom] = useAtom(createProtocolAtom)
+ const { watch } = useFormContext()
const robotType = watch(ROBOT_FIELD_NAME)
const isOtherPipettesSelected = watch(PIPETTES_FIELD_NAME) === TWO_PIPETTES
const isOpentronsOT2Selected = robotType === OPENTRONS_OT2
@@ -91,7 +80,7 @@ export function InstrumentsSection(): JSX.Element | null {
const pipetteOptions = useMemo(() => {
const allPipetteOptions = getAllPipetteNames('maxVolume', 'channels')
.filter(name =>
- (robotType === OT2_ROBOT_TYPE ? OT2_PIPETTES : OT3_PIPETTES).includes(
+ (robotType === OPENTRONS_OT2 ? OT2_PIPETTES : OT3_PIPETTES).includes(
name
)
)
@@ -103,16 +92,6 @@ export function InstrumentsSection(): JSX.Element | null {
return [{ name: t('none'), value: NO_PIPETTES }, ...allPipetteOptions]
}, [robotType])
- function handleConfirmButtonClick(): void {
- const step =
- currentStep > INSTRUMENTS_STEP ? currentStep : INSTRUMENTS_STEP + 1
-
- setCreateProtocolAtom({
- currentStep: step,
- focusStep: step,
- })
- }
-
return (
)}
-
-
-
-
)
}
-const ButtonContainer = styled.div`
- display: ${DISPLAY_FLEX};
- justify-content: ${JUSTIFY_FLEX_END};
-`
-
const PipettesDropdown = styled.div<{ isOpentronsOT2Selected?: boolean }>`
display: flex;
flex-direction: column;
diff --git a/opentrons-ai-client/src/organisms/LabwareLiquidsSection/__tests__/LabwareLiquidsSection.test.tsx b/opentrons-ai-client/src/organisms/LabwareLiquidsSection/__tests__/LabwareLiquidsSection.test.tsx
index ce5f40e8e52..9e4d76391f0 100644
--- a/opentrons-ai-client/src/organisms/LabwareLiquidsSection/__tests__/LabwareLiquidsSection.test.tsx
+++ b/opentrons-ai-client/src/organisms/LabwareLiquidsSection/__tests__/LabwareLiquidsSection.test.tsx
@@ -1,4 +1,4 @@
-import { fireEvent, screen } from '@testing-library/react'
+import { fireEvent, screen, waitFor } from '@testing-library/react'
import { describe, it, expect } from 'vitest'
import { renderWithProviders } from '../../../__testing-utils__'
import { i18n } from '../../../i18n'
@@ -15,6 +15,8 @@ const TestFormProviderComponent = () => {
return (
+
+ {`form is ${methods.formState.isValid ? 'valid' : 'invalid'}`}
)
}
@@ -31,7 +33,6 @@ describe('LabwareLiquidsSection', () => {
expect(screen.getByText('Add Opentrons labware')).toBeInTheDocument()
expect(screen.getByText('No labware added yet')).toBeInTheDocument()
- expect(screen.getByText('Confirm')).toBeInTheDocument()
})
it('should not display the no labware added message if labwares have been added', async () => {
@@ -51,20 +52,27 @@ describe('LabwareLiquidsSection', () => {
expect(screen.queryByText('No labware added yet')).not.toBeInTheDocument()
})
- // it('should enable the confirm button when labwares have been added', async () => {
- // render()
+ it('should update form state to valid when labwares and liquids have been added', async () => {
+ render()
- // expect(screen.getByText('Confirm')).toBeDisabled()
+ await waitFor(() => {
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
+ })
+ const addButton = screen.getByText('Add Opentrons labware')
+ fireEvent.click(addButton)
- // const addButton = screen.getByText('Add Opentrons labware')
- // fireEvent.click(addButton)
+ fireEvent.click(screen.getByText('Tip rack'))
+ fireEvent.click(
+ await screen.findByText('Opentrons Flex 96 Tip Rack 1000 µL')
+ )
+ fireEvent.click(screen.getByText('Save'))
- // fireEvent.click(screen.getByText('Tip rack'))
- // fireEvent.click(
- // await screen.findByText('Opentrons Flex 96 Tip Rack 1000 µL')
- // )
- // fireEvent.click(screen.getByText('Save'))
+ fireEvent.change(screen.getByRole('textbox'), {
+ target: { value: 'test liquid' },
+ })
- // expect(screen.getByText('Confirm')).toBeEnabled()
- // })
+ await waitFor(() => {
+ expect(screen.getByText('form is valid')).toBeInTheDocument()
+ })
+ })
})
diff --git a/opentrons-ai-client/src/organisms/LabwareLiquidsSection/index.tsx b/opentrons-ai-client/src/organisms/LabwareLiquidsSection/index.tsx
index 627b3a5ea76..24d50e32f21 100644
--- a/opentrons-ai-client/src/organisms/LabwareLiquidsSection/index.tsx
+++ b/opentrons-ai-client/src/organisms/LabwareLiquidsSection/index.tsx
@@ -1,21 +1,14 @@
import {
COLORS,
DIRECTION_COLUMN,
- DISPLAY_FLEX,
EmptySelectorButton,
Flex,
InfoScreen,
- JUSTIFY_FLEX_END,
- LargeButton,
SPACING,
StyledText,
} from '@opentrons/components'
import { useFormContext } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
-import styled from 'styled-components'
-import { useAtom } from 'jotai'
-import { createProtocolAtom } from '../../resources/atoms'
-import { LABWARE_LIQUIDS_STEP } from '../ProtocolSectionsContainer'
import { useState } from 'react'
import { LabwareModal } from '../LabwareModal'
import { ControlledLabwareListItems } from '../../molecules/ControlledLabwareListItems'
@@ -31,29 +24,12 @@ export const LIQUIDS_FIELD_NAME = 'liquids'
export function LabwareLiquidsSection(): JSX.Element | null {
const { t } = useTranslation('create_protocol')
- const {
- formState: { isValid },
- setValue,
- watch,
- } = useFormContext()
- const [{ currentStep }, setCreateProtocolAtom] = useAtom(createProtocolAtom)
+ const { setValue, watch } = useFormContext()
const [displayLabwareModal, setDisplayLabwareModal] = useState(false)
const labwares: DisplayLabware[] = watch(LABWARES_FIELD_NAME) ?? []
const liquids: string[] = watch(LIQUIDS_FIELD_NAME) ?? []
- function handleConfirmButtonClick(): void {
- const step =
- currentStep > LABWARE_LIQUIDS_STEP
- ? currentStep
- : LABWARE_LIQUIDS_STEP + 1
-
- setCreateProtocolAtom({
- currentStep: step,
- focusStep: step,
- })
- }
-
return (
-
-
-
-
)
}
-
-const ButtonContainer = styled.div`
- display: ${DISPLAY_FLEX};
- justify-content: ${JUSTIFY_FLEX_END};
-`
diff --git a/opentrons-ai-client/src/organisms/LabwareModal/index.tsx b/opentrons-ai-client/src/organisms/LabwareModal/index.tsx
index baf83087877..0fcb6b17de1 100644
--- a/opentrons-ai-client/src/organisms/LabwareModal/index.tsx
+++ b/opentrons-ai-client/src/organisms/LabwareModal/index.tsx
@@ -19,7 +19,7 @@ import { createPortal } from 'react-dom'
import { reduce } from 'lodash'
import { ListButtonCheckbox } from '../../atoms/ListButtonCheckbox/ListButtonCheckbox'
import { LABWARES_FIELD_NAME } from '../LabwareLiquidsSection'
-import { getAllDefinitions } from '../../resources/utils'
+import { getOnlyLatestDefs } from '../../resources/utils'
import type { DisplayLabware } from '../LabwareLiquidsSection'
import type {
LabwareDefByDefURI,
@@ -56,7 +56,7 @@ export function LabwareModal({
const searchFilter = (termToCheck: string): boolean =>
termToCheck.toLowerCase().includes(searchTerm.toLowerCase())
- const defs = getAllDefinitions()
+ const defs = getOnlyLatestDefs()
const labwareByCategory: Record<
string,
@@ -229,10 +229,18 @@ export function LabwareModal({
setValue(
LABWARES_FIELD_NAME,
[
- ...selectedLabwares.map(labwareURI => ({
- labwareURI,
- count: 1,
- })),
+ ...selectedLabwares.map(labwareURI => {
+ const existingLabware = labwares.find(
+ lw => lw.labwareURI === labwareURI
+ )
+ return {
+ labwareURI,
+ count:
+ existingLabware != null
+ ? existingLabware.count
+ : 1,
+ }
+ }),
],
{ shouldValidate: true }
)
diff --git a/opentrons-ai-client/src/organisms/ModulesSection/__tests__/ModulesSection.test.tsx b/opentrons-ai-client/src/organisms/ModulesSection/__tests__/ModulesSection.test.tsx
index 16c7046f152..652df2a1b95 100644
--- a/opentrons-ai-client/src/organisms/ModulesSection/__tests__/ModulesSection.test.tsx
+++ b/opentrons-ai-client/src/organisms/ModulesSection/__tests__/ModulesSection.test.tsx
@@ -15,6 +15,8 @@ const TestFormProviderComponent = () => {
return (
+
+ {`form is ${methods.formState.isValid ? 'valid' : 'invalid'}`}
)
}
@@ -26,12 +28,11 @@ const render = (): ReturnType => {
}
describe('ModulesSection', () => {
- it('should render modules buttons, no modules added yet, and confirm button', async () => {
+ it('should render modules buttons and no modules added yet', async () => {
render()
- expect(screen.getAllByRole('button').length).toBe(5)
+ expect(screen.getAllByRole('button').length).toBe(4)
expect(screen.getByText('No modules added yet')).toBeInTheDocument()
- expect(screen.getByText('Confirm')).toBeInTheDocument()
})
it('should render a list item with the selected module if user clicks the module button', () => {
@@ -71,20 +72,11 @@ describe('ModulesSection', () => {
expect(screen.getAllByText('Heater-Shaker Module GEN1').length).toBe(1)
})
- it('should disable confirm button when all fields are not filled', async () => {
- render()
-
- const confirmButton = screen.getByRole('button', { name: 'Confirm' })
- await waitFor(() => {
- expect(confirmButton).not.toBeEnabled()
- })
- })
-
- it('should render with Confirm button enabled, modules are not required', async () => {
+ it('should render with form state valid, modules are not required', async () => {
render()
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled()
+ expect(screen.getByText('form is valid')).toBeInTheDocument()
})
})
})
diff --git a/opentrons-ai-client/src/organisms/ModulesSection/index.tsx b/opentrons-ai-client/src/organisms/ModulesSection/index.tsx
index 85f068bc226..2531d9aab37 100644
--- a/opentrons-ai-client/src/organisms/ModulesSection/index.tsx
+++ b/opentrons-ai-client/src/organisms/ModulesSection/index.tsx
@@ -1,18 +1,11 @@
import {
DIRECTION_COLUMN,
- DISPLAY_FLEX,
Flex,
InfoScreen,
- JUSTIFY_FLEX_END,
- LargeButton,
SPACING,
} from '@opentrons/components'
import { useFormContext } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
-import styled from 'styled-components'
-import { useAtom } from 'jotai'
-import { createProtocolAtom } from '../../resources/atoms'
-import { MODULES_STEP } from '../ProtocolSectionsContainer'
import { ControlledEmptySelectorButtonGroup } from '../../molecules/ControlledEmptySelectorButtonGroup'
import { ModuleListItemGroup } from '../../molecules/ModuleListItemGroup'
import type { ModuleType, ModuleModel } from '@opentrons/shared-data'
@@ -31,11 +24,7 @@ export const MODULES_FIELD_NAME = 'modules'
export function ModulesSection(): JSX.Element | null {
const { t } = useTranslation('create_protocol')
- const {
- formState: { isValid },
- watch,
- } = useFormContext()
- const [{ currentStep }, setCreateProtocolAtom] = useAtom(createProtocolAtom)
+ const { watch } = useFormContext()
const modules: DisplayModules[] = [
{
@@ -60,15 +49,6 @@ export function ModulesSection(): JSX.Element | null {
},
]
- function handleConfirmButtonClick(): void {
- const step = currentStep > MODULES_STEP ? currentStep : MODULES_STEP + 1
-
- setCreateProtocolAtom({
- currentStep: step,
- focusStep: step,
- })
- }
-
const modulesWatch: DisplayModules[] = watch(MODULES_FIELD_NAME) ?? []
return (
@@ -84,19 +64,6 @@ export function ModulesSection(): JSX.Element | null {
)}
-
-
-
-
)
}
-
-const ButtonContainer = styled.div`
- display: ${DISPLAY_FLEX};
- justify-content: ${JUSTIFY_FLEX_END};
-`
diff --git a/opentrons-ai-client/src/organisms/ProtocolSectionsContainer/index.tsx b/opentrons-ai-client/src/organisms/ProtocolSectionsContainer/index.tsx
index 7240a83ae4f..3946d6a5cf5 100644
--- a/opentrons-ai-client/src/organisms/ProtocolSectionsContainer/index.tsx
+++ b/opentrons-ai-client/src/organisms/ProtocolSectionsContainer/index.tsx
@@ -1,15 +1,23 @@
-import { DIRECTION_COLUMN, Flex, SPACING } from '@opentrons/components'
+import {
+ DIRECTION_COLUMN,
+ DISPLAY_FLEX,
+ Flex,
+ JUSTIFY_FLEX_END,
+ LargeButton,
+ SPACING,
+} from '@opentrons/components'
import { useTranslation } from 'react-i18next'
import { Accordion } from '../../molecules/Accordion'
import styled from 'styled-components'
import { ApplicationSection } from '../../organisms/ApplicationSection'
import { createProtocolAtom } from '../../resources/atoms'
import { useAtom } from 'jotai'
-import { useFormContext } from 'react-hook-form'
import { InstrumentsSection } from '../InstrumentsSection'
import { ModulesSection } from '../ModulesSection'
import { LabwareLiquidsSection } from '../LabwareLiquidsSection'
import { StepsSection } from '../StepsSection'
+import { useFormContext } from 'react-hook-form'
+import { COLUMN } from '@opentrons/shared-data'
export const APPLICATION_STEP = 0
export const INSTRUMENTS_STEP = 1
@@ -22,62 +30,83 @@ export function ProtocolSectionsContainer(): JSX.Element | null {
const {
formState: { isValid },
} = useFormContext()
- const [{ currentStep, focusStep }, setCreateProtocolAtom] = useAtom(
+ const [{ currentSection, focusSection }, setCreateProtocolAtom] = useAtom(
createProtocolAtom
)
function handleSectionClick(stepNumber: number): void {
- currentStep >= stepNumber &&
+ currentSection >= stepNumber &&
isValid &&
setCreateProtocolAtom({
- currentStep,
- focusStep: stepNumber,
+ currentSection,
+ focusSection: stepNumber,
})
}
function displayCheckmark(stepNumber: number): boolean {
- return currentStep > stepNumber && focusStep !== stepNumber
+ return currentSection > stepNumber && focusSection !== stepNumber
+ }
+
+ function handleConfirmButtonClick(): void {
+ const step =
+ currentSection > focusSection ? currentSection : focusSection + 1
+
+ setCreateProtocolAtom({
+ currentSection: step,
+ focusSection: step,
+ })
}
return (
{[
{
- stepNumber: APPLICATION_STEP,
+ sectionNumber: APPLICATION_STEP,
title: 'application_title',
Component: ApplicationSection,
},
{
- stepNumber: INSTRUMENTS_STEP,
+ sectionNumber: INSTRUMENTS_STEP,
title: 'instruments_title',
Component: InstrumentsSection,
},
{
- stepNumber: MODULES_STEP,
+ sectionNumber: MODULES_STEP,
title: 'modules_title',
Component: ModulesSection,
},
{
- stepNumber: LABWARE_LIQUIDS_STEP,
+ sectionNumber: LABWARE_LIQUIDS_STEP,
title: 'labware_liquids_title',
Component: LabwareLiquidsSection,
},
{
- stepNumber: STEPS_STEP,
+ sectionNumber: STEPS_STEP,
title: 'steps_title',
Component: StepsSection,
},
- ].map(({ stepNumber, title, Component }) => (
+ ].map(({ sectionNumber, title, Component }) => (
{
- handleSectionClick(stepNumber)
+ handleSectionClick(sectionNumber)
}}
- isCompleted={displayCheckmark(stepNumber)}
+ isCompleted={displayCheckmark(sectionNumber)}
>
- {focusStep === stepNumber && }
+ {focusSection === sectionNumber && (
+
+
+
+
+
+
+ )}
))}
@@ -89,3 +118,8 @@ const ProtocolSections = styled(Flex)`
width: 100%;
gap: ${SPACING.spacing16};
`
+
+const ButtonContainer = styled.div`
+ display: ${DISPLAY_FLEX};
+ justify-content: ${JUSTIFY_FLEX_END};
+`
diff --git a/opentrons-ai-client/src/organisms/StepsSection/__tests__/StepsSection.test.tsx b/opentrons-ai-client/src/organisms/StepsSection/__tests__/StepsSection.test.tsx
index 8ef93100bc0..06fc8b30741 100644
--- a/opentrons-ai-client/src/organisms/StepsSection/__tests__/StepsSection.test.tsx
+++ b/opentrons-ai-client/src/organisms/StepsSection/__tests__/StepsSection.test.tsx
@@ -23,6 +23,8 @@ const TestFormProviderComponent = () => {
) : (
{steps}
)}
+
+ {`form is ${methods.formState.isValid ? 'valid' : 'invalid'}`}
)
}
@@ -113,17 +115,17 @@ describe('StepsSection', () => {
expect(screen.getAllByText('description test')[1]).toBeInTheDocument()
})
- it('should enable the confirm button when steps have been added', async () => {
+ it('should update form state to valid when steps have been added', async () => {
render()
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeDisabled()
+ expect(screen.getByText('form is invalid')).toBeInTheDocument()
fireEvent.change(screen.getByRole('textbox'), {
target: { value: 'description test' },
})
await waitFor(() => {
- expect(screen.getByRole('button', { name: 'Confirm' })).toBeEnabled()
+ expect(screen.getByText('form is valid')).toBeInTheDocument()
})
})
})
diff --git a/opentrons-ai-client/src/organisms/StepsSection/index.tsx b/opentrons-ai-client/src/organisms/StepsSection/index.tsx
index b44d0985039..f2fe7dd8024 100644
--- a/opentrons-ai-client/src/organisms/StepsSection/index.tsx
+++ b/opentrons-ai-client/src/organisms/StepsSection/index.tsx
@@ -1,11 +1,8 @@
import {
COLORS,
DIRECTION_COLUMN,
- DISPLAY_FLEX,
EmptySelectorButton,
Flex,
- JUSTIFY_FLEX_END,
- LargeButton,
SPACING,
StyledText,
Tabs,
@@ -13,9 +10,6 @@ import {
import { useFormContext } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
-import { useAtom } from 'jotai'
-import { createProtocolAtom } from '../../resources/atoms'
-import { STEPS_STEP } from '../ProtocolSectionsContainer'
import { useState } from 'react'
import { COLUMN } from '@opentrons/shared-data'
import { ControlledAddTextAreaFields } from '../../molecules/ControlledAddTextAreaFields'
@@ -25,25 +19,11 @@ export const STEPS_FIELD_NAME = 'steps'
export function StepsSection(): JSX.Element | null {
const { t } = useTranslation('create_protocol')
- const {
- formState: { isValid },
- setValue,
- watch,
- } = useFormContext()
- const [{ currentStep }, setCreateProtocolAtom] = useAtom(createProtocolAtom)
+ const { setValue, watch } = useFormContext()
const [isIndividualStep, setIsIndividualStep] = useState(true)
const steps = watch(STEPS_FIELD_NAME) ?? []
- function handleConfirmButtonClick(): void {
- const step = currentStep > STEPS_STEP ? currentStep : STEPS_STEP + 1
-
- setCreateProtocolAtom({
- currentStep: step,
- focusStep: step,
- })
- }
-
return (
)}
-
-
-
-
)
}
-const ButtonContainer = styled.div`
- display: ${DISPLAY_FLEX};
- justify-content: ${JUSTIFY_FLEX_END};
-`
-
const ExampleOrderedList = styled.ol`
margin-left: ${SPACING.spacing20};
font-size: 14px;
diff --git a/opentrons-ai-client/src/pages/CreateProtocol/__tests__/CreateProtocol.test.tsx b/opentrons-ai-client/src/pages/CreateProtocol/__tests__/CreateProtocol.test.tsx
index 4951299f2c6..919e5f735e8 100644
--- a/opentrons-ai-client/src/pages/CreateProtocol/__tests__/CreateProtocol.test.tsx
+++ b/opentrons-ai-client/src/pages/CreateProtocol/__tests__/CreateProtocol.test.tsx
@@ -260,7 +260,7 @@ describe('CreateProtocol', () => {
expect(mockNavigate).toHaveBeenCalledWith('/chat')
expect(mockUseTrackEvent).toHaveBeenCalledWith({
name: 'submit-prompt',
- properties: { prompt: expect.any(String) },
+ properties: { isCreateOrUpdate: 'create', prompt: expect.any(String) },
})
})
})
diff --git a/opentrons-ai-client/src/pages/CreateProtocol/index.tsx b/opentrons-ai-client/src/pages/CreateProtocol/index.tsx
index 0012a429107..525c79154b9 100644
--- a/opentrons-ai-client/src/pages/CreateProtocol/index.tsx
+++ b/opentrons-ai-client/src/pages/CreateProtocol/index.tsx
@@ -9,6 +9,8 @@ import { useEffect, useRef, useState } from 'react'
import { PromptPreview } from '../../molecules/PromptPreview'
import { useForm, FormProvider } from 'react-hook-form'
import {
+ chatDataAtom,
+ chatHistoryAtom,
createProtocolAtom,
createProtocolChatAtom,
headerWithMeterAtom,
@@ -29,7 +31,7 @@ import { ResizeBar } from '../../atoms/ResizeBar'
export interface CreateProtocolFormData {
application: {
scientificApplication: string
- otherApplication?: string
+ otherApplication: string
description: string
}
instruments: {
@@ -50,9 +52,13 @@ const TOTAL_STEPS = 5
export function CreateProtocol(): JSX.Element | null {
const { t } = useTranslation('create_protocol')
const [, setHeaderWithMeterAtom] = useAtom(headerWithMeterAtom)
- const [{ currentStep }, setCreateProtocolAtom] = useAtom(createProtocolAtom)
+ const [{ currentSection }, setCreateProtocolAtom] = useAtom(
+ createProtocolAtom
+ )
const [, setCreateProtocolChatAtom] = useAtom(createProtocolChatAtom)
const [, setUpdateProtocolChatAtom] = useAtom(updateProtocolChatAtom)
+ const [, setChatHistoryAtom] = useAtom(chatHistoryAtom)
+ const [, setChatData] = useAtom(chatDataAtom)
const navigate = useNavigate()
const trackEvent = useTrackEvent()
const [leftWidth, setLeftWidth] = useState(50)
@@ -77,8 +83,23 @@ export function CreateProtocol(): JSX.Element | null {
},
})
- // Reset the update protocol chat atom when navigating to the create protocol page
+ // Reset the chat data atom and protocol atoms when navigating to the update protocol page
useEffect(() => {
+ setCreateProtocolChatAtom({
+ prompt: '',
+ regenerate: false,
+ scientific_application_type: '',
+ description: '',
+ robots: 'opentrons_flex',
+ mounts: [],
+ flexGripper: false,
+ modules: [],
+ labware: [],
+ liquids: [],
+ steps: [],
+ fake: false,
+ fake_id: 0,
+ })
setUpdateProtocolChatAtom({
prompt: '',
protocol_text: '',
@@ -88,6 +109,8 @@ export function CreateProtocol(): JSX.Element | null {
fake: false,
fake_id: 0,
})
+ setChatHistoryAtom([])
+ setChatData([])
}, [])
useEffect(() => {
@@ -95,7 +118,7 @@ export function CreateProtocol(): JSX.Element | null {
displayHeaderWithMeter: true,
progress: calculateProgress(),
})
- }, [currentStep])
+ }, [currentSection])
useEffect(() => {
return () => {
@@ -106,8 +129,8 @@ export function CreateProtocol(): JSX.Element | null {
methods.reset()
setCreateProtocolAtom({
- currentStep: 0,
- focusStep: 0,
+ currentSection: 0,
+ focusSection: 0,
})
}
}, [])
@@ -138,7 +161,7 @@ export function CreateProtocol(): JSX.Element | null {
}, [isResizing])
function calculateProgress(): number {
- return currentStep > 0 ? currentStep / TOTAL_STEPS : 0
+ return currentSection > 0 ? currentSection / TOTAL_STEPS : 0
}
function handleMouseDown(
@@ -184,6 +207,7 @@ export function CreateProtocol(): JSX.Element | null {
trackEvent({
name: 'submit-prompt',
properties: {
+ isCreateOrUpdate: 'create',
prompt: chatPromptData,
},
})
@@ -209,7 +233,7 @@ export function CreateProtocol(): JSX.Element | null {
diff --git a/opentrons-ai-client/src/organisms/UpdateProtocol/__tests__/UpdateProtocol.test.tsx b/opentrons-ai-client/src/pages/UpdateProtocol/__tests__/UpdateProtocol.test.tsx
similarity index 73%
rename from opentrons-ai-client/src/organisms/UpdateProtocol/__tests__/UpdateProtocol.test.tsx
rename to opentrons-ai-client/src/pages/UpdateProtocol/__tests__/UpdateProtocol.test.tsx
index 04c3ad3b167..f69d4b88bf8 100644
--- a/opentrons-ai-client/src/organisms/UpdateProtocol/__tests__/UpdateProtocol.test.tsx
+++ b/opentrons-ai-client/src/pages/UpdateProtocol/__tests__/UpdateProtocol.test.tsx
@@ -122,4 +122,53 @@ describe('Update Protocol', () => {
})
expect(mockNavigate).toHaveBeenCalledWith('/chat')
})
+
+ it('should call trackEvent when submit prompt button is clicked', async () => {
+ render()
+
+ // upload file
+ const blobParts: BlobPart[] = [
+ 'x = 1\n',
+ 'x = 2\n',
+ 'x = 3\n',
+ 'x = 4\n',
+ 'print("x is 1.")\n',
+ ]
+ const file = new File(blobParts, 'test-file.py', { type: 'text/python' })
+ fireEvent.drop(screen.getByTestId('file_drop_zone'), {
+ dataTransfer: {
+ files: [file],
+ },
+ })
+
+ // input description
+ const describeInput = screen.getByRole('textbox')
+ fireEvent.change(describeInput, { target: { value: 'Test description' } })
+
+ expect(screen.getByDisplayValue('Test description')).toBeInTheDocument()
+
+ // select update type
+ const applicationDropdown = screen.getByText('Select an option')
+ fireEvent.click(applicationDropdown)
+
+ const basicOtherOption = screen.getByText('Other')
+ fireEvent.click(basicOtherOption)
+
+ const submitPromptButton = screen.getByText('Submit prompt')
+ await waitFor(() => {
+ expect(submitPromptButton).toBeEnabled()
+ })
+
+ fireEvent.click(submitPromptButton)
+
+ await waitFor(() => {
+ expect(mockUseTrackEvent).toHaveBeenCalledWith({
+ name: 'submit-prompt',
+ properties: {
+ isCreateOrUpdate: 'update',
+ prompt: expect.any(String),
+ },
+ })
+ })
+ })
})
diff --git a/opentrons-ai-client/src/organisms/UpdateProtocol/index.tsx b/opentrons-ai-client/src/pages/UpdateProtocol/index.tsx
similarity index 91%
rename from opentrons-ai-client/src/organisms/UpdateProtocol/index.tsx
rename to opentrons-ai-client/src/pages/UpdateProtocol/index.tsx
index 9b47ce4c251..6d12c3f700a 100644
--- a/opentrons-ai-client/src/organisms/UpdateProtocol/index.tsx
+++ b/opentrons-ai-client/src/pages/UpdateProtocol/index.tsx
@@ -4,7 +4,6 @@ import {
DIRECTION_COLUMN,
DIRECTION_ROW,
Flex,
- InputField,
JUSTIFY_CENTER,
JUSTIFY_END,
LargeButton,
@@ -21,13 +20,16 @@ import { Trans, useTranslation } from 'react-i18next'
import { FileUpload } from '../../molecules/FileUpload'
import { useNavigate } from 'react-router-dom'
import {
+ chatHistoryAtom,
createProtocolChatAtom,
headerWithMeterAtom,
updateProtocolChatAtom,
+ chatDataAtom,
} from '../../resources/atoms'
import { CSSTransition } from 'react-transition-group'
import { useAtom } from 'jotai'
import { useTrackEvent } from '../../resources/hooks/useTrackEvent'
+import { TextAreaField } from '../../atoms/TextAreaField'
interface UpdateOptionsDropdown extends DropdownOption {
value: UpdateOptions
@@ -105,16 +107,19 @@ export function UpdateProtocol(): JSX.Element {
const [headerState, setHeaderWithMeterAtom] = useAtom(headerWithMeterAtom)
const [updateType, setUpdateType] = useState(null)
const [detailsValue, setDetailsValue] = useState('')
- const [, setUpdatePromptAtom] = useAtom(updateProtocolChatAtom)
+ const [, setUpdateProtocolChatAtom] = useAtom(updateProtocolChatAtom)
const [, setCreateProtocolChatAtom] = useAtom(createProtocolChatAtom)
+ const [, setChatHistoryAtom] = useAtom(chatHistoryAtom)
+ const [, setChatData] = useAtom(chatDataAtom)
const [fileValue, setFile] = useState(null)
const [pythonText, setPythonTextValue] = useState('')
const [errorText, setErrorText] = useState(null)
- // Reset the create protocol chat atom when navigating to the update protocol page
+ // Reset the chat data atom and protocol atoms when navigating to the update protocol page
useEffect(() => {
setCreateProtocolChatAtom({
prompt: '',
+ regenerate: false,
scientific_application_type: '',
description: '',
robots: 'opentrons_flex',
@@ -127,6 +132,17 @@ export function UpdateProtocol(): JSX.Element {
fake: false,
fake_id: 0,
})
+ setUpdateProtocolChatAtom({
+ prompt: '',
+ protocol_text: '',
+ regenerate: false,
+ update_type: 'adapt_python_protocol',
+ update_details: '',
+ fake: false,
+ fake_id: 0,
+ })
+ setChatHistoryAtom([])
+ setChatData([])
}, [])
useEffect(() => {
@@ -156,7 +172,7 @@ export function UpdateProtocol(): JSX.Element {
setHeaderWithMeterAtom,
])
- const handleInputChange = (event: ChangeEvent): void => {
+ const handleInputChange = (event: ChangeEvent): void => {
setDetailsValue(event.target.value)
}
@@ -171,7 +187,6 @@ export function UpdateProtocol(): JSX.Element {
if (typeof text === 'string' && text !== '') {
setErrorText(null)
- console.log('File read successfully:\n', text)
setPythonTextValue(text)
} else {
setErrorText(t('file_length_error'))
@@ -196,7 +211,7 @@ export function UpdateProtocol(): JSX.Element {
console.log(chatPrompt)
- setUpdatePromptAtom({
+ setUpdateProtocolChatAtom({
prompt: chatPrompt,
protocol_text: pythonText,
regenerate: false,
@@ -209,6 +224,7 @@ export function UpdateProtocol(): JSX.Element {
trackEvent({
name: 'submit-prompt',
properties: {
+ isCreateOrUpdate: 'update',
prompt: chatPrompt,
},
})
@@ -310,10 +326,10 @@ export function UpdateProtocol(): JSX.Element {
/>
{t('provide_details_of_changes')}
-
([])
/** CreateProtocolChatAtom is for the prefilled userprompt when navigating to the chat page from Create New protocol page */
export const createProtocolChatAtom = atom({
prompt: '',
+ regenerate: false,
scientific_application_type: '',
description: '',
robots: 'opentrons_flex',
@@ -40,6 +41,15 @@ export const updateProtocolChatAtom = atom({
fake_id: 0,
})
+/** Regenerate protocol atom */
+export const regenerateProtocolAtom = atom<{
+ isCreateOrUpdateProtocol: boolean
+ regenerate: boolean
+}>({
+ isCreateOrUpdateProtocol: false,
+ regenerate: false,
+})
+
/** Scroll to bottom of chat atom */
export const scrollToBottomAtom = atom(false)
@@ -59,9 +69,9 @@ export const headerWithMeterAtom = atom({
progress: 0,
})
-export const createProtocolAtom = atom({
- currentStep: 0,
- focusStep: 0,
+export const createProtocolAtom = atom({
+ currentSection: 0,
+ focusSection: 0,
})
export const displayExitConfirmModalAtom = atom(false)
diff --git a/opentrons-ai-client/src/resources/types.ts b/opentrons-ai-client/src/resources/types.ts
index 7a84eba1054..7e16e1a8642 100644
--- a/opentrons-ai-client/src/resources/types.ts
+++ b/opentrons-ai-client/src/resources/types.ts
@@ -15,6 +15,7 @@ export interface ChatData {
export interface CreatePrompt {
/** the prompt that is generated by the create protocol page */
prompt: string
+ regenerate: boolean
scientific_application_type: string
description: string
robots: 'opentrons_flex' | 'opentrons_ot2' | string
@@ -84,9 +85,9 @@ export interface HeaderWithMeterAtomProps {
progress: number
}
-export interface createProtocolAtomProps {
- currentStep: number
- focusStep: number
+export interface CreateProtocolAtomProps {
+ currentSection: number
+ focusSection: number
}
export interface PromptData {
diff --git a/opentrons-ai-client/src/resources/utils/createProtocolUtils.tsx b/opentrons-ai-client/src/resources/utils/createProtocolUtils.tsx
index 1c5899a7d0e..a2ccffd988b 100644
--- a/opentrons-ai-client/src/resources/utils/createProtocolUtils.tsx
+++ b/opentrons-ai-client/src/resources/utils/createProtocolUtils.tsx
@@ -13,7 +13,7 @@ import {
} from '../../organisms/InstrumentsSection'
import type { UseFormWatch } from 'react-hook-form'
import type { CreateProtocolFormData } from '../../pages/CreateProtocol'
-import { getAllDefinitions } from './labware'
+import { getOnlyLatestDefs } from './labware'
import type { CreatePrompt } from '../types'
export function generatePromptPreviewApplicationItems(
@@ -92,10 +92,14 @@ export function generatePromptPreviewLabwareLiquidsItems(
const { labwares, liquids } = watch()
const items: string[] = []
- const defs = getAllDefinitions()
+ const defs = getOnlyLatestDefs()
labwares?.forEach(labware => {
- items.push(getLabwareDisplayName(defs[labware.labwareURI]) as string)
+ items.push(
+ `${labware.count} x ${
+ getLabwareDisplayName(defs[labware.labwareURI]) as string
+ }`
+ )
})
liquids?.forEach(liquid => {
@@ -155,7 +159,7 @@ export function generateChatPrompt(
args_0: CreatePrompt | ((prev: CreatePrompt) => CreatePrompt)
) => void
): string {
- const defs = getAllDefinitions()
+ const defs = getOnlyLatestDefs()
const robotType = t(values.instruments.robot)
const scientificApplication = t(values.application.scientificApplication)
@@ -226,7 +230,11 @@ export function generateChatPrompt(
setCreateProtocolChatAtom({
prompt,
- scientific_application_type: values.application.scientificApplication,
+ regenerate: false,
+ scientific_application_type:
+ values.application.scientificApplication === OTHER
+ ? values.application.otherApplication
+ : values.application.scientificApplication,
description,
robots: values.instruments.robot,
mounts,
diff --git a/opentrons-ai-client/src/resources/utils/labware.ts b/opentrons-ai-client/src/resources/utils/labware.ts
index b0844c57a70..f7bf0ddf427 100644
--- a/opentrons-ai-client/src/resources/utils/labware.ts
+++ b/opentrons-ai-client/src/resources/utils/labware.ts
@@ -2,16 +2,52 @@ import {
LABWAREV2_DO_NOT_LIST,
RETIRED_LABWARE,
getAllDefinitions as _getAllDefinitions,
+ getLabwareDefURI,
+} from '@opentrons/shared-data'
+import { groupBy } from 'lodash'
+import type {
+ LabwareDefByDefURI,
+ LabwareDefinition2,
} from '@opentrons/shared-data'
-import type { LabwareDefByDefURI } from '@opentrons/shared-data'
let _definitions: LabwareDefByDefURI | null = null
+
+const BLOCK_LIST = [...RETIRED_LABWARE, ...LABWAREV2_DO_NOT_LIST]
+
export function getAllDefinitions(): LabwareDefByDefURI {
if (_definitions == null) {
- _definitions = _getAllDefinitions([
- ...RETIRED_LABWARE,
- ...LABWAREV2_DO_NOT_LIST,
- ])
+ _definitions = _getAllDefinitions(BLOCK_LIST)
}
return _definitions
}
+
+// filter out all but the latest version of each labware
+// NOTE: this is similar to labware-library's getOnlyLatestDefs, but this one
+// has the {labwareDefURI: def} shape, instead of an array of labware defs
+let _latestDefs: LabwareDefByDefURI | null = null
+export function getOnlyLatestDefs(): LabwareDefByDefURI {
+ if (!_latestDefs) {
+ const allDefs = getAllDefinitions()
+ const allURIs = Object.keys(allDefs)
+ const labwareDefGroups: Record = groupBy(
+ allURIs.map((uri: string) => allDefs[uri]),
+ d => `${d.namespace}/${d.parameters.loadName}`
+ )
+ _latestDefs = Object.keys(labwareDefGroups).reduce(
+ (acc, groupKey: string) => {
+ const group = labwareDefGroups[groupKey]
+ const allVersions = group.map(d => d.version)
+ const highestVersionNum = Math.max(...allVersions)
+ const resultIdx = group.findIndex(d => d.version === highestVersionNum)
+ const latestDefInGroup = group[resultIdx]
+ return {
+ ...acc,
+ [getLabwareDefURI(latestDefInGroup)]: latestDefInGroup,
+ }
+ },
+ {}
+ )
+ }
+
+ return _latestDefs
+}
diff --git a/opentrons-ai-server/Makefile b/opentrons-ai-server/Makefile
index ecc643d9cd0..2bc7170e931 100644
--- a/opentrons-ai-server/Makefile
+++ b/opentrons-ai-server/Makefile
@@ -75,6 +75,12 @@ deploy: gen-requirements
@echo "Deploying to environment: $(ENV)"
python -m pipenv run python deploy.py --env $(ENV) $(if $(TAG),--tag $(TAG),)
+.PHONY: dry-deploy
+dry-deploy: gen-requirements
+ @echo "Dry run deploying to environment: $(ENV)"
+ @echo "Data is retrieved from AWS but no changes are made"
+ python -m pipenv run python deploy.py --dry --env $(ENV) $(if $(TAG),--tag $(TAG),)
+
.PHONY: prompted-deploy
prompted-deploy: gen-requirements
python -m pipenv run python deploy.py
@@ -132,4 +138,9 @@ run-shell:
.PHONY: shell
shell:
- docker exec -it $(CONTAINER_NAME) /bin/bash]
+ docker exec -it $(CONTAINER_NAME) /bin/bash
+
+.PHONY: test-googlesheet
+test-googlesheet:
+ @echo "Loading environment variables from .env and running test-googlesheet"
+ pipenv run python -m api.integration.google_sheets
diff --git a/opentrons-ai-server/Pipfile b/opentrons-ai-server/Pipfile
index 34b0b8d32dd..4586798349a 100644
--- a/opentrons-ai-server/Pipfile
+++ b/opentrons-ai-server/Pipfile
@@ -17,6 +17,9 @@ beautifulsoup4 = "==4.12.3"
markdownify = "==0.13.1"
structlog = "==24.4.0"
asgi-correlation-id = "==4.3.3"
+gspread = "==6.1.4"
+google-auth = "==2.36.0"
+google-auth-oauthlib = "==1.2.1"
[dev-packages]
docker = "==7.1.0"
diff --git a/opentrons-ai-server/Pipfile.lock b/opentrons-ai-server/Pipfile.lock
index 55811db04cf..a4b9ba0dca5 100644
--- a/opentrons-ai-server/Pipfile.lock
+++ b/opentrons-ai-server/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "20b9e324d809f68cb0465d5e3d98467ceb5860f583fddc347ade1e5ad6a3b6ab"
+ "sha256": "56aef120fbddf42f146e054b7d59ee0f59be75aa6e43f332f86b7ba8fa2499e0"
},
"pipfile-spec": 6,
"requires": {
@@ -26,100 +26,85 @@
},
"aiohttp": {
"hashes": [
- "sha256:02d1d6610588bcd743fae827bd6f2e47e0d09b346f230824b4c6fb85c6065f9c",
- "sha256:03690541e4cc866eef79626cfa1ef4dd729c5c1408600c8cb9e12e1137eed6ab",
- "sha256:0bc059ecbce835630e635879f5f480a742e130d9821fbe3d2f76610a6698ee25",
- "sha256:0c21c82df33b264216abffff9f8370f303dab65d8eee3767efbbd2734363f677",
- "sha256:1298b854fd31d0567cbb916091be9d3278168064fca88e70b8468875ef9ff7e7",
- "sha256:1321658f12b6caffafdc35cfba6c882cb014af86bef4e78c125e7e794dfb927b",
- "sha256:143b0026a9dab07a05ad2dd9e46aa859bffdd6348ddc5967b42161168c24f857",
- "sha256:16e6a51d8bc96b77f04a6764b4ad03eeef43baa32014fce71e882bd71302c7e4",
- "sha256:172ad884bb61ad31ed7beed8be776eb17e7fb423f1c1be836d5cb357a096bf12",
- "sha256:17c272cfe7b07a5bb0c6ad3f234e0c336fb53f3bf17840f66bd77b5815ab3d16",
- "sha256:1a0ee6c0d590c917f1b9629371fce5f3d3f22c317aa96fbdcce3260754d7ea21",
- "sha256:2746d8994ebca1bdc55a1e998feff4e94222da709623bb18f6e5cfec8ec01baf",
- "sha256:2914caa46054f3b5ff910468d686742ff8cff54b8a67319d75f5d5945fd0a13d",
- "sha256:2bbf94d4a0447705b7775417ca8bb8086cc5482023a6e17cdc8f96d0b1b5aba6",
- "sha256:2bd9f3eac515c16c4360a6a00c38119333901b8590fe93c3257a9b536026594d",
- "sha256:2c33fa6e10bb7ed262e3ff03cc69d52869514f16558db0626a7c5c61dde3c29f",
- "sha256:2d37f4718002863b82c6f391c8efd4d3a817da37030a29e2682a94d2716209de",
- "sha256:3668d0c2a4d23fb136a753eba42caa2c0abbd3d9c5c87ee150a716a16c6deec1",
- "sha256:36d4fba838be5f083f5490ddd281813b44d69685db910907636bc5dca6322316",
- "sha256:40ff5b7660f903dc587ed36ef08a88d46840182d9d4b5694e7607877ced698a1",
- "sha256:42775de0ca04f90c10c5c46291535ec08e9bcc4756f1b48f02a0657febe89b10",
- "sha256:482c85cf3d429844396d939b22bc2a03849cb9ad33344689ad1c85697bcba33a",
- "sha256:4e6cb75f8ddd9c2132d00bc03c9716add57f4beff1263463724f6398b813e7eb",
- "sha256:4edc3fd701e2b9a0d605a7b23d3de4ad23137d23fc0dbab726aa71d92f11aaaf",
- "sha256:4fd16b30567c5b8e167923be6e027eeae0f20cf2b8a26b98a25115f28ad48ee0",
- "sha256:5002a02c17fcfd796d20bac719981d2fca9c006aac0797eb8f430a58e9d12431",
- "sha256:51d0a4901b27272ae54e42067bc4b9a90e619a690b4dc43ea5950eb3070afc32",
- "sha256:558b3d223fd631ad134d89adea876e7fdb4c93c849ef195049c063ada82b7d08",
- "sha256:5c070430fda1a550a1c3a4c2d7281d3b8cfc0c6715f616e40e3332201a253067",
- "sha256:5f392ef50e22c31fa49b5a46af7f983fa3f118f3eccb8522063bee8bfa6755f8",
- "sha256:60555211a006d26e1a389222e3fab8cd379f28e0fbf7472ee55b16c6c529e3a6",
- "sha256:608cecd8d58d285bfd52dbca5b6251ca8d6ea567022c8a0eaae03c2589cd9af9",
- "sha256:60ad5b8a7452c0f5645c73d4dad7490afd6119d453d302cd5b72b678a85d6044",
- "sha256:63649309da83277f06a15bbdc2a54fbe75efb92caa2c25bb57ca37762789c746",
- "sha256:6ebdc3b3714afe1b134b3bbeb5f745eed3ecbcff92ab25d80e4ef299e83a5465",
- "sha256:6f3c6648aa123bcd73d6f26607d59967b607b0da8ffcc27d418a4b59f4c98c7c",
- "sha256:7003f33f5f7da1eb02f0446b0f8d2ccf57d253ca6c2e7a5732d25889da82b517",
- "sha256:776e9f3c9b377fcf097c4a04b241b15691e6662d850168642ff976780609303c",
- "sha256:85711eec2d875cd88c7eb40e734c4ca6d9ae477d6f26bd2b5bb4f7f60e41b156",
- "sha256:87d1e4185c5d7187684d41ebb50c9aeaaaa06ca1875f4c57593071b0409d2444",
- "sha256:8a3f063b41cc06e8d0b3fcbbfc9c05b7420f41287e0cd4f75ce0a1f3d80729e6",
- "sha256:8b3fb28a9ac8f2558760d8e637dbf27aef1e8b7f1d221e8669a1074d1a266bb2",
- "sha256:8bd9125dd0cc8ebd84bff2be64b10fdba7dc6fd7be431b5eaf67723557de3a31",
- "sha256:8be1a65487bdfc285bd5e9baf3208c2132ca92a9b4020e9f27df1b16fab998a9",
- "sha256:8cc0d13b4e3b1362d424ce3f4e8c79e1f7247a00d792823ffd640878abf28e56",
- "sha256:8d9d10d10ec27c0d46ddaecc3c5598c4db9ce4e6398ca872cdde0525765caa2f",
- "sha256:8debb45545ad95b58cc16c3c1cc19ad82cffcb106db12b437885dbee265f0ab5",
- "sha256:91aa966858593f64c8a65cdefa3d6dc8fe3c2768b159da84c1ddbbb2c01ab4ef",
- "sha256:9331dd34145ff105177855017920dde140b447049cd62bb589de320fd6ddd582",
- "sha256:99f9678bf0e2b1b695e8028fedac24ab6770937932eda695815d5a6618c37e04",
- "sha256:9fdf5c839bf95fc67be5794c780419edb0dbef776edcfc6c2e5e2ffd5ee755fa",
- "sha256:a14e4b672c257a6b94fe934ee62666bacbc8e45b7876f9dd9502d0f0fe69db16",
- "sha256:a19caae0d670771ea7854ca30df76f676eb47e0fd9b2ee4392d44708f272122d",
- "sha256:a35ed3d03910785f7d9d6f5381f0c24002b2b888b298e6f941b2fc94c5055fcd",
- "sha256:a61df62966ce6507aafab24e124e0c3a1cfbe23c59732987fc0fd0d71daa0b88",
- "sha256:a6e00c8a92e7663ed2be6fcc08a2997ff06ce73c8080cd0df10cc0321a3168d7",
- "sha256:ac3196952c673822ebed8871cf8802e17254fff2a2ed4835d9c045d9b88c5ec7",
- "sha256:ac74e794e3aee92ae8f571bfeaa103a141e409863a100ab63a253b1c53b707eb",
- "sha256:ad3675c126f2a95bde637d162f8231cff6bc0bc9fbe31bd78075f9ff7921e322",
- "sha256:aeebd3061f6f1747c011e1d0b0b5f04f9f54ad1a2ca183e687e7277bef2e0da2",
- "sha256:ba1a599255ad6a41022e261e31bc2f6f9355a419575b391f9655c4d9e5df5ff5",
- "sha256:bbdb8def5268f3f9cd753a265756f49228a20ed14a480d151df727808b4531dd",
- "sha256:c2555e4949c8d8782f18ef20e9d39730d2656e218a6f1a21a4c4c0b56546a02e",
- "sha256:c2695c61cf53a5d4345a43d689f37fc0f6d3a2dc520660aec27ec0f06288d1f9",
- "sha256:c2b627d3c8982691b06d89d31093cee158c30629fdfebe705a91814d49b554f8",
- "sha256:c46131c6112b534b178d4e002abe450a0a29840b61413ac25243f1291613806a",
- "sha256:c54dc329cd44f7f7883a9f4baaefe686e8b9662e2c6c184ea15cceee587d8d69",
- "sha256:c7d7cafc11d70fdd8801abfc2ff276744ae4cb39d8060b6b542c7e44e5f2cfc2",
- "sha256:cb0b2d5d51f96b6cc19e6ab46a7b684be23240426ae951dcdac9639ab111b45e",
- "sha256:d15a29424e96fad56dc2f3abed10a89c50c099f97d2416520c7a543e8fddf066",
- "sha256:d1f5c9169e26db6a61276008582d945405b8316aae2bb198220466e68114a0f5",
- "sha256:d271f770b52e32236d945911b2082f9318e90ff835d45224fa9e28374303f729",
- "sha256:d646fdd74c25bbdd4a055414f0fe32896c400f38ffbdfc78c68e62812a9e0257",
- "sha256:d6e395c3d1f773cf0651cd3559e25182eb0c03a2777b53b4575d8adc1149c6e9",
- "sha256:d7c071235a47d407b0e93aa6262b49422dbe48d7d8566e1158fecc91043dd948",
- "sha256:d97273a52d7f89a75b11ec386f786d3da7723d7efae3034b4dda79f6f093edc1",
- "sha256:dcf354661f54e6a49193d0b5653a1b011ba856e0b7a76bda2c33e4c6892f34ea",
- "sha256:e3e7fabedb3fe06933f47f1538df7b3a8d78e13d7167195f51ca47ee12690373",
- "sha256:e525b69ee8a92c146ae5b4da9ecd15e518df4d40003b01b454ad694a27f498b5",
- "sha256:e709d6ac598c5416f879bb1bae3fd751366120ac3fa235a01de763537385d036",
- "sha256:e83dfefb4f7d285c2d6a07a22268344a97d61579b3e0dce482a5be0251d672ab",
- "sha256:e86260b76786c28acf0b5fe31c8dca4c2add95098c709b11e8c35b424ebd4f5b",
- "sha256:e883b61b75ca6efc2541fcd52a5c8ccfe288b24d97e20ac08fdf343b8ac672ea",
- "sha256:f0a44bb40b6aaa4fb9a5c1ee07880570ecda2065433a96ccff409c9c20c1624a",
- "sha256:f82ace0ec57c94aaf5b0e118d4366cff5889097412c75aa14b4fd5fc0c44ee3e",
- "sha256:f9ca09414003c0e96a735daa1f071f7d7ed06962ef4fa29ceb6c80d06696d900",
- "sha256:fa430b871220dc62572cef9c69b41e0d70fcb9d486a4a207a5de4c1f25d82593",
- "sha256:fc262c3df78c8ff6020c782d9ce02e4bcffe4900ad71c0ecdad59943cba54442",
- "sha256:fcd546782d03181b0b1d20b43d612429a90a68779659ba8045114b867971ab71",
- "sha256:fd4ceeae2fb8cabdd1b71c82bfdd39662473d3433ec95b962200e9e752fb70d0",
- "sha256:fec5fac7aea6c060f317f07494961236434928e6f4374e170ef50b3001e14581"
- ],
- "markers": "python_version >= '3.8'",
- "version": "==3.10.9"
+ "sha256:024409c1b1d6076d0ed933dcebd7e4fc6f3320a227bfa0c1b6b93a8b5a146f04",
+ "sha256:04b24497b3baf15035730de5f207ade88a67d4483a5f16ced7ece348933a5b47",
+ "sha256:08474e71772a516ba2e2167b4707af8361d2c452b3d8a5364c984f4867869499",
+ "sha256:0e7a0762cc29cd3acd01a4d2b547b3af7956ad230ebb80b529a8e4f3e4740fe8",
+ "sha256:104deb7873681273c5daa13c41924693df394043a118dae90387d35bc5531788",
+ "sha256:104ea21994b1403e4c1b398866f1187c1694fa291314ad7216ec1d8ec6b49f38",
+ "sha256:113bf06b029143e94a47c4f36e11a8b7e396e9d1f1fc8cea58e6b7e370cfed38",
+ "sha256:12071dd2cc95ba81e0f2737bebcb98b2a8656015e87772e84e8fb9e635b5da6e",
+ "sha256:170fb2324826bb9f08055a8291f42192ae5ee2f25b2966c8f0f4537c61d73a7b",
+ "sha256:21b4545e8d96870da9652930c5198366605ff8f982757030e2148cf341e5746b",
+ "sha256:229ae13959a5f499d90ffbb4b9eac2255d8599315027d6f7c22fa9803a94d5b1",
+ "sha256:2ec5efbc872b00ddd85e3904059d274f284cff314e13f48776050ca2c58f451d",
+ "sha256:31b91ff3a1fcb206a1fa76e0de1f08c9ffb1dc0deb7296fa2618adfe380fc676",
+ "sha256:329f5059e0bf6983dceebac8e6ed20e75eaff6163b3414f4a4cb59e0d7037672",
+ "sha256:37f8cf3c43f292d9bb3e6760476c2b55b9663a581fad682a586a410c43a7683e",
+ "sha256:3e1ed8d152cccceffb1ee7a2ac227c16372e453fb11b3aeaa56783049b85d3f6",
+ "sha256:3ed360d6672a9423aad39902a4e9fe305464d20ed7931dbdba30a4625782d875",
+ "sha256:40dc9446cff326672fcbf93efdb8ef7e949824de1097624efe4f61ac7f0d2c43",
+ "sha256:4d218d3eca40196384ad3b481309c56fd60e664128885d1734da0a8aa530d433",
+ "sha256:4e4e155968040e32c124a89852a1a5426d0e920a35f4331e1b3949037bfe93a3",
+ "sha256:4f698aa61879df64425191d41213dfd99efdc1627e6398e6d7aa5c312fac9702",
+ "sha256:508cfcc99534b1282595357592d8367b44392b21f6eb5d4dc021f8d0d809e94d",
+ "sha256:577c7429f8869fa30186fc2c9eee64d75a30b51b61f26aac9725866ae5985cfd",
+ "sha256:57e17c6d71f2dc857a8a1d09be1be7802e35d90fb4ba4b06cf1aab6414a57894",
+ "sha256:5ecc2fb1a0a9d48cf773add34196cddf7e488e48e9596e090849751bf43098f4",
+ "sha256:600b1d9f86a130131915e2f2127664311b33902c486b21a747d626f5144b4471",
+ "sha256:62502b8ffee8c6a4b5c6bf99d1de277d42bf51b2fb713975d9b63b560150b7ac",
+ "sha256:62a2f5268b672087c45b33479ba1bb1d5a48c6d76c133cfce3a4f77410c200d1",
+ "sha256:6362f50a6f0e5482c4330d2151cb682779230683da0e155c15ec9fc58cb50b6a",
+ "sha256:6533dd06df3d17d1756829b68b365b1583929b54082db8f65083a4184bf68322",
+ "sha256:6c5a6958f4366496004cf503d847093d464814543f157ef3b738bbf604232415",
+ "sha256:72cd984f7f14e8c01b3e38f18f39ea85dba84e52ea05e37116ba5e2a72eef396",
+ "sha256:76d6ee8bb132f8ee0fcb0e205b4708ddb6fba524eb515ee168113063d825131b",
+ "sha256:7867d0808614f04e78e0a8d5a2c1f8ac6bc626a0c0e2f62be48be6b749e2f8b2",
+ "sha256:7d664e5f937c08adb7908ea9f391fbf2928a9b09cb412ac0aba602bde9e499e4",
+ "sha256:85ae6f182be72c3531915e90625cc65afce4df8a0fc4988bd52d8a5d5faaeb68",
+ "sha256:89a96a0696dc67d548f69cb518c581a7a33cc1f26ab42229dea1709217c9d926",
+ "sha256:8b323b5d3aef7dd811424c269322eec58a977c0c8152e650159e47210d900504",
+ "sha256:8c47a0ba6c2b3d3e5715f8338d657badd21f778c6be16701922c65521c5ecfc9",
+ "sha256:8fef105113d56e817cb9bcc609667ee461321413a7b972b03f5b4939f40f307c",
+ "sha256:900ff74d78eb580ae4aa5883242893b123a0c442a46570902500f08d6a7e6696",
+ "sha256:9095580806d9ed07c0c29b23364a0b1fb78258ef9f4bddf7e55bac0e475d4edf",
+ "sha256:91d3991fad8b65e5dbc13cd95669ea689fe0a96ff63e4e64ac24ed724e4f8103",
+ "sha256:9231d610754724273a6ac05a1f177979490bfa6f84d49646df3928af2e88cfd5",
+ "sha256:97056d3422594e0787733ac4c45bef58722d452f4dc6615fee42f59fe51707dd",
+ "sha256:a896059b6937d1a22d8ee8377cdcd097bd26cd8c653b8f972051488b9baadee9",
+ "sha256:aabc4e92cb153636d6be54e84dad1b252ddb9aebe077942b6dcffe5e468d476a",
+ "sha256:ad14cdc0fba4df31c0f6e06c21928c5b924725cbf60d0ccc5f6e7132636250e9",
+ "sha256:ae36ae52b0c22fb69fb8b744eff82a20db512a29eafc6e3a4ab43b17215b219d",
+ "sha256:b3e4fb7f5354d39490d8209aefdf5830b208d01c7293a2164e404312c3d8bc55",
+ "sha256:b40c304ab01e89ad0aeeecf91bbaa6ae3b00e27b796c9e8d50b71a4a7e885cc8",
+ "sha256:b7349205bb163318dcc102329d30be59a647a3d24c82c3d91ed35b7e7301ea7e",
+ "sha256:b8b95a63a8e8b5f0464bd8b1b0d59d2bec98a59b6aacc71e9be23df6989b3dfb",
+ "sha256:bb2e82e515e268b965424ecabebd91834a41b36260b6ef5db015ee12ddb28ef3",
+ "sha256:c0315978b2a4569e03fb59100f6a7e7d23f718a4521491f5c13d946d37549f3d",
+ "sha256:c1828e10c3a49e2b234b87600ecb68a92b8a8dcf8b99bca9447f16c4baaa1630",
+ "sha256:c1c49bc393d854d4421ebc174a0a41f9261f50d3694d8ca277146cbbcfd24ee7",
+ "sha256:c415b9601ff50709d6050c8a9281733a9b042b9e589265ac40305b875cf9c463",
+ "sha256:c54c635d1f52490cde7ef3a423645167a8284e452a35405d5c7dc1242a8e75c9",
+ "sha256:c5e6a1f8b0268ffa1c84d7c3558724956002ba8361176e76406233e704bbcffb",
+ "sha256:c98a596ac20e8980cc6f34c0c92a113e98eb08f3997c150064d26d2aeb043e5a",
+ "sha256:cd0834e4260eab78671b81d34f110fbaac449563e48d419cec0030d9a8e58693",
+ "sha256:cdad66685fcf2ad14ce522cf849d4a025f4fd206d6cfc3f403d9873e4c243b03",
+ "sha256:d1ea006426edf7e1299c52a58b0443158012f7a56fed3515164b60bfcb1503a9",
+ "sha256:d33b4490026968bdc7f0729b9d87a3a6b1e09043557d2fc1c605c6072deb2f11",
+ "sha256:d5cae4cd271e20b7ab757e966cc919186b9f02535418ab36c471a5377ef4deaa",
+ "sha256:dd505a1121ad5b666191840b7bd1d8cb917df2647deeca6f3474331b72452362",
+ "sha256:e1668ef2f3a7ec9881f4b6a917e5f97c87a343fa6b0d5fc826b7b0297ddd0887",
+ "sha256:e7bcfcede95531589295f56e924702cef7f9685c9e4e5407592e04ded6a65bf3",
+ "sha256:ebf610c37df4f09c71c9bbf8309b4b459107e6fe889ac0d7e16f6e4ebd975f86",
+ "sha256:f3bf5c132eb48002bcc3825702d241d35b4e9585009e65e9dcf9c4635d0b7424",
+ "sha256:f40380c96dd407dfa84eb2d264e68aa47717b53bdbe210a59cc3c35a4635f195",
+ "sha256:f57a0de48dda792629e7952d34a0c7b81ea336bb9b721391c7c58145b237fe55",
+ "sha256:f6b925c7775ab857bdc1e52e1f5abcae7d18751c09b751aeb641a5276d9b990e",
+ "sha256:f8f0d79b923070f25674e4ea8f3d61c9d89d24d9598d50ff32c5b9b23c79a25b",
+ "sha256:feca9fafa4385aea6759c171cd25ea82f7375312fca04178dae35331be45e538"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==3.11.0"
},
"aiosignal": {
"hashes": [
@@ -139,11 +124,11 @@
},
"anyio": {
"hashes": [
- "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb",
- "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"
+ "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c",
+ "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"
],
"markers": "python_version >= '3.9'",
- "version": "==4.6.0"
+ "version": "==4.6.2.post1"
},
"asgi-correlation-id": {
"hashes": [
@@ -173,11 +158,19 @@
},
"bytecode": {
"hashes": [
- "sha256:0a1dc340cac823cff605609b8b214f7f9bf80418c6b9e0fc8c6db1793c27137d",
- "sha256:7263239a8d3f70fc7c303862b20cd2c6788052e37ce0a26e67309d280e985984"
+ "sha256:06676a3c3bccc9d3dc73ee625650ea57df2bc117358826f4f290f0e1faa42292",
+ "sha256:76080b7c0eb9e7e17f961d61fd06e933aa47f3b753770a3249537439d8203a25"
],
"markers": "python_version >= '3.12'",
- "version": "==0.15.1"
+ "version": "==0.16.0"
+ },
+ "cachetools": {
+ "hashes": [
+ "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292",
+ "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==5.5.0"
},
"cattrs": {
"hashes": [
@@ -270,99 +263,114 @@
},
"charset-normalizer": {
"hashes": [
- "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027",
- "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087",
- "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786",
- "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8",
- "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09",
- "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185",
- "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574",
- "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e",
- "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519",
- "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898",
- "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269",
- "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3",
- "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f",
- "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6",
- "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8",
- "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a",
- "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73",
- "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc",
- "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714",
- "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2",
- "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc",
- "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce",
- "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d",
- "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e",
- "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6",
- "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269",
- "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96",
- "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d",
- "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a",
- "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4",
- "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77",
- "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d",
- "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0",
- "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed",
- "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068",
- "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac",
- "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25",
- "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8",
- "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab",
- "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26",
- "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2",
- "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db",
- "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f",
- "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5",
- "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99",
- "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c",
- "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d",
- "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811",
- "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa",
- "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a",
- "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03",
- "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b",
- "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04",
- "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c",
- "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001",
- "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458",
- "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389",
- "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99",
- "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985",
- "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537",
- "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238",
- "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f",
- "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d",
- "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796",
- "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a",
- "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143",
- "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8",
- "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c",
- "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5",
- "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5",
- "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711",
- "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4",
- "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6",
- "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c",
- "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7",
- "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4",
- "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b",
- "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae",
- "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12",
- "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c",
- "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae",
- "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8",
- "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887",
- "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b",
- "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4",
- "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f",
- "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5",
- "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33",
- "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
- "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
+ "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621",
+ "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6",
+ "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8",
+ "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912",
+ "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c",
+ "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b",
+ "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d",
+ "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d",
+ "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95",
+ "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e",
+ "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565",
+ "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64",
+ "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab",
+ "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be",
+ "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e",
+ "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907",
+ "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0",
+ "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2",
+ "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62",
+ "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62",
+ "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23",
+ "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc",
+ "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284",
+ "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca",
+ "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455",
+ "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858",
+ "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b",
+ "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594",
+ "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc",
+ "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db",
+ "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b",
+ "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea",
+ "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6",
+ "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920",
+ "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749",
+ "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7",
+ "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd",
+ "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99",
+ "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242",
+ "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee",
+ "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129",
+ "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2",
+ "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51",
+ "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee",
+ "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8",
+ "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b",
+ "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613",
+ "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742",
+ "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe",
+ "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3",
+ "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5",
+ "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631",
+ "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7",
+ "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15",
+ "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c",
+ "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea",
+ "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417",
+ "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250",
+ "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88",
+ "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca",
+ "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa",
+ "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99",
+ "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149",
+ "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41",
+ "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574",
+ "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0",
+ "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f",
+ "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d",
+ "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654",
+ "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3",
+ "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19",
+ "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90",
+ "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578",
+ "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9",
+ "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1",
+ "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51",
+ "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719",
+ "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236",
+ "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a",
+ "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c",
+ "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade",
+ "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944",
+ "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc",
+ "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6",
+ "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6",
+ "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27",
+ "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6",
+ "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2",
+ "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12",
+ "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf",
+ "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114",
+ "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7",
+ "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf",
+ "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d",
+ "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b",
+ "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed",
+ "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03",
+ "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4",
+ "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67",
+ "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365",
+ "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a",
+ "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748",
+ "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b",
+ "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079",
+ "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"
],
"markers": "python_full_version >= '3.7.0'",
- "version": "==3.3.2"
+ "version": "==3.4.0"
},
"click": {
"hashes": [
@@ -374,35 +382,35 @@
},
"cryptography": {
"hashes": [
- "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494",
- "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806",
- "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d",
- "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062",
- "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2",
- "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4",
- "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1",
- "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85",
- "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84",
- "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042",
- "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d",
- "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962",
- "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2",
- "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa",
- "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d",
- "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365",
- "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96",
- "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47",
- "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d",
- "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d",
- "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c",
- "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb",
- "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277",
- "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172",
- "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034",
- "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a",
- "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"
- ],
- "version": "==43.0.1"
+ "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362",
+ "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4",
+ "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa",
+ "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83",
+ "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff",
+ "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805",
+ "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6",
+ "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664",
+ "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08",
+ "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e",
+ "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18",
+ "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f",
+ "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73",
+ "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5",
+ "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984",
+ "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd",
+ "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3",
+ "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e",
+ "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405",
+ "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2",
+ "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c",
+ "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995",
+ "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73",
+ "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16",
+ "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7",
+ "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd",
+ "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"
+ ],
+ "version": "==43.0.3"
},
"dataclasses-json": {
"hashes": [
@@ -528,11 +536,11 @@
},
"envier": {
"hashes": [
- "sha256:4e7e398cb09a8dd360508ef7e12511a152355426d2544b8487a34dad27cc20ad",
- "sha256:65099cf3aa9b3b3b4b92db2f7d29e2910672e085b76f7e587d2167561a834add"
+ "sha256:3309a01bb3d8850c9e7a31a5166d5a836846db2faecb79b9cb32654dd50ca9f9",
+ "sha256:73609040a76be48bbcb97074d9969666484aa0de706183a6e9ef773156a8a6a9"
],
"markers": "python_version >= '3.7'",
- "version": "==0.5.2"
+ "version": "==0.6.1"
},
"fastapi": {
"hashes": [
@@ -553,94 +561,127 @@
},
"frozenlist": {
"hashes": [
- "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7",
- "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98",
- "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad",
- "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5",
- "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae",
- "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e",
- "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a",
- "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701",
- "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d",
- "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6",
- "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6",
- "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106",
- "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75",
- "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868",
- "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a",
- "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0",
- "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1",
- "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826",
- "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec",
- "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6",
- "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950",
- "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19",
- "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0",
- "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8",
- "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a",
- "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09",
- "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86",
- "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c",
- "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5",
- "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b",
- "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b",
- "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d",
- "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0",
- "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea",
- "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776",
- "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a",
- "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897",
- "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7",
- "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09",
- "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9",
- "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe",
- "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd",
- "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742",
- "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09",
- "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0",
- "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932",
- "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1",
- "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a",
- "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49",
- "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d",
- "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7",
- "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480",
- "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89",
- "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e",
- "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b",
- "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82",
- "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb",
- "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068",
- "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8",
- "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b",
- "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb",
- "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2",
- "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11",
- "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b",
- "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc",
- "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0",
- "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497",
- "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17",
- "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0",
- "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2",
- "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439",
- "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5",
- "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac",
- "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825",
- "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887",
- "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced",
- "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"
- ],
- "markers": "python_version >= '3.8'",
- "version": "==1.4.1"
+ "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e",
+ "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf",
+ "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6",
+ "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a",
+ "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d",
+ "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f",
+ "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28",
+ "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b",
+ "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9",
+ "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2",
+ "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec",
+ "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2",
+ "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c",
+ "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336",
+ "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4",
+ "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d",
+ "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b",
+ "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c",
+ "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10",
+ "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08",
+ "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942",
+ "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8",
+ "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f",
+ "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10",
+ "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5",
+ "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6",
+ "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21",
+ "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c",
+ "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d",
+ "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923",
+ "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608",
+ "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de",
+ "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17",
+ "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0",
+ "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f",
+ "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641",
+ "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c",
+ "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a",
+ "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0",
+ "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9",
+ "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab",
+ "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f",
+ "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3",
+ "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a",
+ "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784",
+ "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604",
+ "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d",
+ "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5",
+ "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03",
+ "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e",
+ "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953",
+ "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee",
+ "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d",
+ "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817",
+ "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3",
+ "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039",
+ "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f",
+ "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9",
+ "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf",
+ "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76",
+ "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba",
+ "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171",
+ "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb",
+ "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439",
+ "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631",
+ "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972",
+ "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d",
+ "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869",
+ "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9",
+ "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411",
+ "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723",
+ "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2",
+ "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b",
+ "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99",
+ "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e",
+ "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840",
+ "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3",
+ "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb",
+ "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3",
+ "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0",
+ "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca",
+ "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45",
+ "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e",
+ "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f",
+ "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5",
+ "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307",
+ "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e",
+ "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2",
+ "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778",
+ "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a",
+ "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30",
+ "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==1.5.0"
},
"fsspec": {
"hashes": [
- "sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8",
- "sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b"
+ "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871",
+ "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"
],
"markers": "python_version >= '3.8'",
- "version": "==2024.9.0"
+ "version": "==2024.10.0"
+ },
+ "google-auth": {
+ "hashes": [
+ "sha256:51a15d47028b66fd36e5c64a82d2d57480075bccc7da37cde257fc94177a61fb",
+ "sha256:545e9618f2df0bcbb7dcbc45a546485b1212624716975a1ea5ae8149ce769ab1"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.7'",
+ "version": "==2.36.0"
+ },
+ "google-auth-oauthlib": {
+ "hashes": [
+ "sha256:2d58a27262d55aa1b87678c3ba7142a080098cbc2024f903c62355deb235d91f",
+ "sha256:afd0cad092a2eaa53cd8e8298557d6de1034c6cb4a740500b5357b648af97263"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.6'",
+ "version": "==1.2.1"
},
"greenlet": {
"hashes": [
@@ -721,6 +762,15 @@
"markers": "python_version < '3.13' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
"version": "==3.1.1"
},
+ "gspread": {
+ "hashes": [
+ "sha256:b8eec27de7cadb338bb1b9f14a9be168372dee8965c0da32121816b5050ac1de",
+ "sha256:c34781c426031a243ad154952b16f21ac56a5af90687885fbee3d1fba5280dcd"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==6.1.4"
+ },
"h11": {
"hashes": [
"sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d",
@@ -739,44 +789,51 @@
},
"httptools": {
"hashes": [
- "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563",
- "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142",
- "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d",
- "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b",
- "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4",
- "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb",
- "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658",
- "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084",
- "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2",
- "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97",
- "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837",
- "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3",
- "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58",
- "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da",
- "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d",
- "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90",
- "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0",
- "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1",
- "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2",
- "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e",
- "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0",
- "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf",
- "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc",
- "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3",
- "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503",
- "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a",
- "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3",
- "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949",
- "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84",
- "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb",
- "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a",
- "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f",
- "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e",
- "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81",
- "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185",
- "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"
- ],
- "version": "==0.6.1"
+ "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a",
+ "sha256:0e563e54979e97b6d13f1bbc05a96109923e76b901f786a5eae36e99c01237bd",
+ "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2",
+ "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17",
+ "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8",
+ "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3",
+ "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5",
+ "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da",
+ "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0",
+ "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721",
+ "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636",
+ "sha256:40dc6a8e399e15ea525305a2ddba998b0af5caa2566bcd79dcbe8948181eeaff",
+ "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0",
+ "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071",
+ "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c",
+ "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4",
+ "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1",
+ "sha256:703c346571fa50d2e9856a37d7cd9435a25e7fd15e236c397bf224afaa355fe9",
+ "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44",
+ "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083",
+ "sha256:85797e37e8eeaa5439d33e556662cc370e474445d5fab24dcadc65a8ffb04003",
+ "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959",
+ "sha256:94978a49b8f4569ad607cd4946b759d90b285e39c0d4640c6b36ca7a3ddf2efc",
+ "sha256:aafe0f1918ed07b67c1e838f950b1c1fabc683030477e60b335649b8020e1076",
+ "sha256:ab9ba8dcf59de5181f6be44a77458e45a578fc99c31510b8c65b7d5acc3cf490",
+ "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660",
+ "sha256:b799de31416ecc589ad79dd85a0b2657a8fe39327944998dea368c1d4c9e55e6",
+ "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c",
+ "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50",
+ "sha256:d1ffd262a73d7c28424252381a5b854c19d9de5f56f075445d33919a637e3547",
+ "sha256:d3f0d369e7ffbe59c4b6116a44d6a8eb4783aae027f2c0b366cf0aa964185dba",
+ "sha256:d54efd20338ac52ba31e7da78e4a72570cf729fac82bc31ff9199bedf1dc7440",
+ "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988",
+ "sha256:db353d22843cf1028f43c3651581e4bb49374d85692a85f95f7b9a130e1b2cab",
+ "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970",
+ "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1",
+ "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2",
+ "sha256:df959752a0c2748a65ab5387d08287abf6779ae9165916fe053e68ae1fbdc47f",
+ "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81",
+ "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069",
+ "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975",
+ "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f",
+ "sha256:fc411e1c0a7dcd2f902c7c48cf079947a7e65b5485dea9decb82b9105ca71a43"
+ ],
+ "version": "==0.6.4"
},
"httpx": {
"hashes": [
@@ -797,11 +854,11 @@
},
"importlib-metadata": {
"hashes": [
- "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1",
- "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"
+ "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b",
+ "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"
],
"markers": "python_version >= '3.8'",
- "version": "==8.4.0"
+ "version": "==8.5.0"
},
"jinja2": {
"hashes": [
@@ -878,11 +935,11 @@
},
"llama-index-legacy": {
"hashes": [
- "sha256:04221320d84d96ba9ee3e21e5055bd8527cbd769e8f1c60cf0368ed907e012a2",
- "sha256:f6969f1085efb0abebd6367e46f3512020f3f6b9c086f458a519830dd61e8206"
+ "sha256:4b817d7c343fb5f7f00c4410eff519f320013b8d5f24c4fedcf270c471f92038",
+ "sha256:f8a9764e7e134a52bfef5e53d2d62561bfc01fc09874c51cc001df6f5302ae30"
],
"markers": "python_version < '4.0' and python_full_version >= '3.8.1'",
- "version": "==0.9.48.post3"
+ "version": "==0.9.48.post4"
},
"llama-index-llms-openai": {
"hashes": [
@@ -958,78 +1015,78 @@
},
"markupsafe": {
"hashes": [
- "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396",
- "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38",
- "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a",
- "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8",
- "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b",
- "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad",
- "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a",
- "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a",
- "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da",
- "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6",
- "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8",
- "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344",
- "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a",
- "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8",
- "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5",
- "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7",
- "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170",
- "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132",
- "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9",
- "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd",
- "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9",
- "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346",
- "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc",
- "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589",
- "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5",
- "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915",
- "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295",
- "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453",
- "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea",
- "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b",
- "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d",
- "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b",
- "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4",
- "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b",
- "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7",
- "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf",
- "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f",
- "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91",
- "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd",
- "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50",
- "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b",
- "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583",
- "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a",
- "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984",
- "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c",
- "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c",
- "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25",
- "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa",
- "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4",
- "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3",
- "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97",
- "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1",
- "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd",
- "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772",
- "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a",
- "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729",
- "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca",
- "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6",
- "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635",
- "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b",
- "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"
+ "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4",
+ "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30",
+ "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0",
+ "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9",
+ "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396",
+ "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13",
+ "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028",
+ "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca",
+ "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557",
+ "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832",
+ "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0",
+ "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b",
+ "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579",
+ "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a",
+ "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c",
+ "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff",
+ "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c",
+ "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22",
+ "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094",
+ "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb",
+ "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e",
+ "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5",
+ "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a",
+ "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d",
+ "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a",
+ "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b",
+ "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8",
+ "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225",
+ "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c",
+ "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144",
+ "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f",
+ "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87",
+ "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d",
+ "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93",
+ "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf",
+ "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158",
+ "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84",
+ "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb",
+ "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48",
+ "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171",
+ "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c",
+ "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6",
+ "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd",
+ "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d",
+ "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1",
+ "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d",
+ "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca",
+ "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a",
+ "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29",
+ "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe",
+ "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798",
+ "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c",
+ "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8",
+ "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f",
+ "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f",
+ "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a",
+ "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178",
+ "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0",
+ "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79",
+ "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430",
+ "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"
],
"markers": "python_version >= '3.9'",
- "version": "==3.0.1"
+ "version": "==3.0.2"
},
"marshmallow": {
"hashes": [
- "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e",
- "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"
+ "sha256:3a8dfda6edd8dcdbf216c0ede1d1e78d230a6dc9c5a088f58c4083b974a0d468",
+ "sha256:fece2eb2c941180ea1b7fcbd4a83c51bfdd50093fdd3ad2585ee5e1df2508491"
],
- "markers": "python_version >= '3.8'",
- "version": "==3.22.0"
+ "markers": "python_version >= '3.9'",
+ "version": "==3.23.1"
},
"mdurl": {
"hashes": [
@@ -1155,11 +1212,11 @@
},
"networkx": {
"hashes": [
- "sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9",
- "sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2"
+ "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1",
+ "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"
],
"markers": "python_version >= '3.10'",
- "version": "==3.3"
+ "version": "==3.4.2"
},
"nltk": {
"hashes": [
@@ -1211,6 +1268,14 @@
"markers": "python_version >= '3.9'",
"version": "==1.26.4"
},
+ "oauthlib": {
+ "hashes": [
+ "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca",
+ "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"
+ ],
+ "markers": "python_version >= '3.6'",
+ "version": "==3.2.2"
+ },
"openai": {
"hashes": [
"sha256:aa2f381f476f5fa4df8728a34a3e454c321caa064b7b68ab6e9daa1ed082dbf9",
@@ -1222,82 +1287,83 @@
},
"opentelemetry-api": {
"hashes": [
- "sha256:953d5871815e7c30c81b56d910c707588000fff7a3ca1c73e6531911d53065e7",
- "sha256:ed673583eaa5f81b5ce5e86ef7cdaf622f88ef65f0b9aab40b843dcae5bef342"
+ "sha256:6fa7295a12c707f5aebef82da3d9ec5afe6992f3e42bfe7bec0339a44b3518e7",
+ "sha256:bfe86c95576cf19a914497f439fd79c9553a38de0adbdc26f7cfc46b0c00b16c"
],
"markers": "python_version >= '3.8'",
- "version": "==1.27.0"
+ "version": "==1.28.1"
},
"orjson": {
"hashes": [
- "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23",
- "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9",
- "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5",
- "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad",
- "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98",
- "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412",
- "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1",
- "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864",
- "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6",
- "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91",
- "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac",
- "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c",
- "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1",
- "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f",
- "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250",
- "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09",
- "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0",
- "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225",
- "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354",
- "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f",
- "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e",
- "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469",
- "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c",
- "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12",
- "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3",
- "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3",
- "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149",
- "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb",
- "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2",
- "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2",
- "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f",
- "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0",
- "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a",
- "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58",
- "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe",
- "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09",
- "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e",
- "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2",
- "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c",
- "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313",
- "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6",
- "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93",
- "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7",
- "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866",
- "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c",
- "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b",
- "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5",
- "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175",
- "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9",
- "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0",
- "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff",
- "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20",
- "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5",
- "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960",
- "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024",
- "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd",
- "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"
- ],
- "markers": "python_version >= '3.8'",
- "version": "==3.10.7"
+ "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5",
+ "sha256:0efabbf839388a1dab5b72b5d3baedbd6039ac83f3b55736eb9934ea5494d258",
+ "sha256:10f416b2a017c8bd17f325fb9dee1fb5cdd7a54e814284896b7c3f2763faa017",
+ "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6",
+ "sha256:1789d9db7968d805f3d94aae2c25d04014aae3a2fa65b1443117cd462c6da647",
+ "sha256:19b3763e8bbf8ad797df6b6b5e0fc7c843ec2e2fc0621398534e0c6400098f87",
+ "sha256:1a1222ffcee8a09476bbdd5d4f6f33d06d0d6642df2a3d78b7a195ca880d669b",
+ "sha256:1be83a13312e5e58d633580c5eb8d0495ae61f180da2722f20562974188af205",
+ "sha256:1f39728c7f7d766f1f5a769ce4d54b5aaa4c3f92d5b84817053cc9995b977acc",
+ "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51",
+ "sha256:461311b693d3d0a060439aa669c74f3603264d4e7a08faa68c47ae5a863f352d",
+ "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97",
+ "sha256:4bfb30c891b530f3f80e801e3ad82ef150b964e5c38e1fb8482441c69c35c61c",
+ "sha256:4d83f87582d223e54efb2242a79547611ba4ebae3af8bae1e80fa9a0af83bb7f",
+ "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67",
+ "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0",
+ "sha256:52ca832f17d86a78cbab86cdc25f8c13756ebe182b6fc1a97d534051c18a08de",
+ "sha256:52e5834d7d6e58a36846e059d00559cb9ed20410664f3ad156cd2cc239a11230",
+ "sha256:5576b1e5a53a5ba8f8df81872bb0878a112b3ebb1d392155f00f54dd86c83ff6",
+ "sha256:63fc9d5fe1d4e8868f6aae547a7b8ba0a2e592929245fff61d633f4caccdcdd6",
+ "sha256:655a493bac606655db9a47fe94d3d84fc7f3ad766d894197c94ccf0c5408e7d3",
+ "sha256:65cd3e3bb4fbb4eddc3c1e8dce10dc0b73e808fcb875f9fab40c81903dd9323e",
+ "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981",
+ "sha256:6dade64687f2bd7c090281652fe18f1151292d567a9302b34c2dbb92a3872f1f",
+ "sha256:6f67c570602300c4befbda12d153113b8974a3340fdcf3d6de095ede86c06d92",
+ "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d",
+ "sha256:77b0fed6f209d76c1c39f032a70df2d7acf24b1812ca3e6078fd04e8972685a3",
+ "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19",
+ "sha256:80c00d4acded0c51c98754fe8218cb49cb854f0f7eb39ea4641b7f71732d2cb7",
+ "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b",
+ "sha256:82f07c550a6ccd2b9290849b22316a609023ed851a87ea888c0456485a7d196a",
+ "sha256:86b9dd983857970c29e4c71bb3e95ff085c07d3e83e7c46ebe959bac07ebd80b",
+ "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a",
+ "sha256:96ed1de70fcb15d5fed529a656df29f768187628727ee2788344e8a51e1c1350",
+ "sha256:9fd0ad1c129bc9beb1154c2655f177620b5beaf9a11e0d10bac63ef3fce96950",
+ "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55",
+ "sha256:a2fc947e5350fdce548bfc94f434e8760d5cafa97fb9c495d2fef6757aa02ec0",
+ "sha256:a3f29634260708c200c4fe148e42b4aae97d7b9fee417fbdd74f8cfc265f15b0",
+ "sha256:afacfd1ab81f46dedd7f6001b6d4e8de23396e4884cd3c3436bd05defb1a6446",
+ "sha256:b592597fe551d518f42c5a2eb07422eb475aa8cfdc8c51e6da7054b836b26782",
+ "sha256:b7fcfc6f7ca046383fb954ba528587e0f9336828b568282b27579c49f8e16aad",
+ "sha256:b9546b278c9fb5d45380f4809e11b4dd9844ca7aaf1134024503e134ed226161",
+ "sha256:bc274ac261cc69260913b2d1610760e55d3c0801bb3457ba7b9004420b6b4270",
+ "sha256:bd9a187742d3ead9df2e49240234d728c67c356516cf4db018833a86f20ec18c",
+ "sha256:c46294faa4e4d0eb73ab68f1a794d2cbf7bab33b1dda2ac2959ffb7c61591899",
+ "sha256:c95f2ecafe709b4e5c733b5e2768ac569bed308623c85806c395d9cca00e08af",
+ "sha256:cb4d0bea56bba596723d73f074c420aec3b2e5d7d30698bc56e6048066bd560c",
+ "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe",
+ "sha256:d496c74fc2b61341e3cefda7eec21b7854c5f672ee350bc55d9a4997a8a95204",
+ "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d",
+ "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec",
+ "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b",
+ "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5",
+ "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef",
+ "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284",
+ "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433",
+ "sha256:f4c57ea78a753812f528178aa2f1c57da633754c91d2124cb28991dab4c79a54",
+ "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==3.10.11"
},
"packaging": {
"hashes": [
- "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
- "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
+ "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759",
+ "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"
],
"markers": "python_version >= '3.8'",
- "version": "==24.1"
+ "version": "==24.2"
},
"pandas": {
"hashes": [
@@ -1349,89 +1415,84 @@
},
"pillow": {
"hashes": [
- "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885",
- "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea",
- "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df",
- "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5",
- "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c",
- "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d",
- "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd",
- "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06",
- "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908",
- "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a",
- "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be",
- "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0",
- "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b",
- "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80",
- "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a",
- "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e",
- "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9",
- "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696",
- "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b",
- "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309",
- "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e",
- "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab",
- "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d",
- "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060",
- "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d",
- "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d",
- "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4",
- "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3",
- "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6",
- "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb",
- "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94",
- "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b",
- "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496",
- "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0",
- "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319",
- "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b",
- "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856",
- "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef",
- "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680",
- "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b",
- "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42",
- "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e",
- "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597",
- "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a",
- "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8",
- "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3",
- "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736",
- "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da",
- "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126",
- "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd",
- "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5",
- "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b",
- "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026",
- "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b",
- "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc",
- "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46",
- "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2",
- "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c",
- "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe",
- "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984",
- "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a",
- "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70",
- "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca",
- "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b",
- "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91",
- "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3",
- "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84",
- "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1",
- "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5",
- "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be",
- "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f",
- "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc",
- "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9",
- "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e",
- "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141",
- "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef",
- "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22",
- "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27",
- "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e",
- "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"
- ],
- "markers": "python_version >= '3.8'",
- "version": "==10.4.0"
+ "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7",
+ "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5",
+ "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903",
+ "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2",
+ "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38",
+ "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2",
+ "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9",
+ "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f",
+ "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc",
+ "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8",
+ "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d",
+ "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2",
+ "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316",
+ "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a",
+ "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25",
+ "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd",
+ "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba",
+ "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc",
+ "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273",
+ "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa",
+ "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a",
+ "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b",
+ "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a",
+ "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae",
+ "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291",
+ "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97",
+ "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06",
+ "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904",
+ "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b",
+ "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b",
+ "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8",
+ "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527",
+ "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947",
+ "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb",
+ "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003",
+ "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5",
+ "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f",
+ "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739",
+ "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944",
+ "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830",
+ "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f",
+ "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3",
+ "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4",
+ "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84",
+ "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7",
+ "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6",
+ "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6",
+ "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9",
+ "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de",
+ "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4",
+ "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47",
+ "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd",
+ "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50",
+ "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c",
+ "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086",
+ "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba",
+ "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306",
+ "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699",
+ "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e",
+ "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488",
+ "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa",
+ "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2",
+ "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3",
+ "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9",
+ "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923",
+ "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2",
+ "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790",
+ "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734",
+ "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916",
+ "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1",
+ "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f",
+ "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798",
+ "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb",
+ "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2",
+ "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==11.0.0"
},
"propcache": {
"hashes": [
@@ -1539,20 +1600,36 @@
},
"protobuf": {
"hashes": [
- "sha256:2c69461a7fcc8e24be697624c09a839976d82ae75062b11a0972e41fd2cd9132",
- "sha256:35cfcb15f213449af7ff6198d6eb5f739c37d7e4f1c09b5d0641babf2cc0c68f",
- "sha256:52235802093bd8a2811abbe8bf0ab9c5f54cca0a751fdd3f6ac2a21438bffece",
- "sha256:59379674ff119717404f7454647913787034f03fe7049cbef1d74a97bb4593f0",
- "sha256:5e8a95246d581eef20471b5d5ba010d55f66740942b95ba9b872d918c459452f",
- "sha256:87317e9bcda04a32f2ee82089a204d3a2f0d3c8aeed16568c7daf4756e4f1fe0",
- "sha256:8ddc60bf374785fb7cb12510b267f59067fa10087325b8e1855b898a0d81d276",
- "sha256:a8b9403fc70764b08d2f593ce44f1d2920c5077bf7d311fefec999f8c40f78b7",
- "sha256:c0ea0123dac3399a2eeb1a1443d82b7afc9ff40241433296769f7da42d142ec3",
- "sha256:ca53faf29896c526863366a52a8f4d88e69cd04ec9571ed6082fa117fac3ab36",
- "sha256:eeea10f3dc0ac7e6b4933d32db20662902b4ab81bf28df12218aa389e9c2102d"
+ "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24",
+ "sha256:135658402f71bbd49500322c0f736145731b16fc79dc8f367ab544a17eab4535",
+ "sha256:27b246b3723692bf1068d5734ddaf2fccc2cdd6e0c9b47fe099244d80200593b",
+ "sha256:3e6101d095dfd119513cde7259aa703d16c6bbdfae2554dfe5cfdbe94e32d548",
+ "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584",
+ "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b",
+ "sha256:70585a70fc2dd4818c51287ceef5bdba6387f88a578c86d47bb34669b5552c36",
+ "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135",
+ "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868",
+ "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687",
+ "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==5.28.3"
+ },
+ "pyasn1": {
+ "hashes": [
+ "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629",
+ "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==0.6.1"
+ },
+ "pyasn1-modules": {
+ "hashes": [
+ "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd",
+ "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"
],
"markers": "python_version >= '3.8'",
- "version": "==5.28.2"
+ "version": "==0.4.1"
},
"pycparser": {
"hashes": [
@@ -1711,11 +1788,11 @@
},
"python-multipart": {
"hashes": [
- "sha256:045e1f98d719c1ce085ed7f7e1ef9d8ccc8c02ba02b5566d5f7521410ced58cb",
- "sha256:43dcf96cf65888a9cd3423544dd0d75ac10f7aa0c3c28a175bbcd00c9ce1aebf"
+ "sha256:15dc4f487e0a9476cc1201261188ee0940165cffc94429b6fc565c4d3045cb5d",
+ "sha256:41330d831cae6e2f22902704ead2826ea038d0419530eadff3ea80175aec5538"
],
"markers": "python_version >= '3.8'",
- "version": "==0.0.12"
+ "version": "==0.0.17"
},
"pytz": {
"hashes": [
@@ -1785,103 +1862,103 @@
},
"regex": {
"hashes": [
- "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623",
- "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199",
- "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664",
- "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f",
- "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca",
- "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066",
- "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca",
- "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39",
- "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d",
- "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6",
- "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35",
- "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408",
- "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5",
- "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a",
- "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9",
- "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92",
- "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766",
- "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168",
- "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca",
- "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508",
- "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df",
- "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf",
- "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b",
- "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4",
- "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268",
- "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6",
- "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c",
- "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62",
- "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231",
- "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36",
- "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba",
- "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4",
- "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e",
- "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822",
- "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4",
- "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d",
- "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71",
- "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50",
- "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d",
- "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad",
- "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8",
- "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8",
- "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8",
- "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd",
- "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16",
- "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664",
- "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a",
- "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f",
- "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd",
- "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a",
- "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9",
- "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199",
- "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d",
- "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963",
- "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009",
- "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a",
- "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679",
- "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96",
- "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42",
- "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8",
- "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e",
- "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7",
- "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8",
- "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802",
- "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366",
- "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137",
- "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784",
- "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29",
- "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3",
- "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771",
- "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60",
- "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a",
- "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4",
- "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0",
- "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84",
- "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd",
- "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1",
- "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776",
- "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142",
- "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89",
- "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c",
- "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8",
- "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35",
- "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a",
- "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86",
- "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9",
- "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64",
- "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554",
- "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85",
- "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb",
- "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0",
- "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8",
- "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb",
- "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"
- ],
- "markers": "python_version >= '3.8'",
- "version": "==2024.9.11"
+ "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c",
+ "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60",
+ "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d",
+ "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d",
+ "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67",
+ "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773",
+ "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0",
+ "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef",
+ "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad",
+ "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe",
+ "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3",
+ "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114",
+ "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4",
+ "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39",
+ "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e",
+ "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3",
+ "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7",
+ "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d",
+ "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e",
+ "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a",
+ "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7",
+ "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f",
+ "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0",
+ "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54",
+ "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b",
+ "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c",
+ "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd",
+ "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57",
+ "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34",
+ "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d",
+ "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f",
+ "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b",
+ "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519",
+ "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4",
+ "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a",
+ "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638",
+ "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b",
+ "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839",
+ "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07",
+ "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf",
+ "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff",
+ "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0",
+ "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f",
+ "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95",
+ "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4",
+ "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e",
+ "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13",
+ "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519",
+ "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2",
+ "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008",
+ "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9",
+ "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc",
+ "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48",
+ "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20",
+ "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89",
+ "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e",
+ "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf",
+ "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b",
+ "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd",
+ "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84",
+ "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29",
+ "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b",
+ "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3",
+ "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45",
+ "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3",
+ "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983",
+ "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e",
+ "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7",
+ "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4",
+ "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e",
+ "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467",
+ "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577",
+ "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001",
+ "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0",
+ "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55",
+ "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9",
+ "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf",
+ "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6",
+ "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e",
+ "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde",
+ "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62",
+ "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df",
+ "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51",
+ "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5",
+ "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86",
+ "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2",
+ "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2",
+ "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0",
+ "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c",
+ "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f",
+ "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6",
+ "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2",
+ "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9",
+ "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==2024.11.6"
},
"requests": {
"hashes": [
@@ -1891,21 +1968,37 @@
"markers": "python_version >= '3.8'",
"version": "==2.32.3"
},
+ "requests-oauthlib": {
+ "hashes": [
+ "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36",
+ "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"
+ ],
+ "markers": "python_version >= '3.4'",
+ "version": "==2.0.0"
+ },
"rich": {
"hashes": [
- "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c",
- "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"
+ "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098",
+ "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"
],
"markers": "python_full_version >= '3.8.0'",
- "version": "==13.9.2"
+ "version": "==13.9.4"
+ },
+ "rsa": {
+ "hashes": [
+ "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7",
+ "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"
+ ],
+ "markers": "python_version >= '3.6' and python_version < '4'",
+ "version": "==4.9"
},
"setuptools": {
"hashes": [
- "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2",
- "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"
+ "sha256:5c4ccb41111392671f02bb5f8436dfc5a9a7185e80500531b133f5775c4163ef",
+ "sha256:87cb777c3b96d638ca02031192d40390e0ad97737e27b6b4fa831bea86f2f829"
],
"markers": "python_version >= '3.12'",
- "version": "==75.1.0"
+ "version": "==75.5.0"
},
"shellingham": {
"hashes": [
@@ -1944,58 +2037,66 @@
"asyncio"
],
"hashes": [
- "sha256:016b2e665f778f13d3c438651dd4de244214b527a275e0acf1d44c05bc6026a9",
- "sha256:032d979ce77a6c2432653322ba4cbeabf5a6837f704d16fa38b5a05d8e21fa00",
- "sha256:0375a141e1c0878103eb3d719eb6d5aa444b490c96f3fedab8471c7f6ffe70ee",
- "sha256:042622a5306c23b972192283f4e22372da3b8ddf5f7aac1cc5d9c9b222ab3ff6",
- "sha256:05c3f58cf91683102f2f0265c0db3bd3892e9eedabe059720492dbaa4f922da1",
- "sha256:0630774b0977804fba4b6bbea6852ab56c14965a2b0c7fc7282c5f7d90a1ae72",
- "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf",
- "sha256:1b56961e2d31389aaadf4906d453859f35302b4eb818d34a26fab72596076bb8",
- "sha256:22b83aed390e3099584b839b93f80a0f4a95ee7f48270c97c90acd40ee646f0b",
- "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc",
- "sha256:2a275a806f73e849e1c309ac11108ea1a14cd7058577aba962cd7190e27c9e3c",
- "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1",
- "sha256:2e795c2f7d7249b75bb5f479b432a51b59041580d20599d4e112b5f2046437a3",
- "sha256:3655af10ebcc0f1e4e06c5900bb33e080d6a1fa4228f502121f28a3b1753cde5",
- "sha256:4668bd8faf7e5b71c0319407b608f278f279668f358857dbfd10ef1954ac9f90",
- "sha256:4c31943b61ed8fdd63dfd12ccc919f2bf95eefca133767db6fbbd15da62078ec",
- "sha256:4fdcd72a789c1c31ed242fd8c1bcd9ea186a98ee8e5408a50e610edfef980d71",
- "sha256:627dee0c280eea91aed87b20a1f849e9ae2fe719d52cbf847c0e0ea34464b3f7",
- "sha256:67219632be22f14750f0d1c70e62f204ba69d28f62fd6432ba05ab295853de9b",
- "sha256:6921ee01caf375363be5e9ae70d08ce7ca9d7e0e8983183080211a062d299468",
- "sha256:69683e02e8a9de37f17985905a5eca18ad651bf592314b4d3d799029797d0eb3",
- "sha256:6a93c5a0dfe8d34951e8a6f499a9479ffb9258123551fa007fc708ae2ac2bc5e",
- "sha256:732e026240cdd1c1b2e3ac515c7a23820430ed94292ce33806a95869c46bd139",
- "sha256:7befc148de64b6060937231cbff8d01ccf0bfd75aa26383ffdf8d82b12ec04ff",
- "sha256:890da8cd1941fa3dab28c5bac3b9da8502e7e366f895b3b8e500896f12f94d11",
- "sha256:89b64cd8898a3a6f642db4eb7b26d1b28a497d4022eccd7717ca066823e9fb01",
- "sha256:8a6219108a15fc6d24de499d0d515c7235c617b2540d97116b663dade1a54d62",
- "sha256:8cdf1a0dbe5ced887a9b127da4ffd7354e9c1a3b9bb330dce84df6b70ccb3a8d",
- "sha256:8d625eddf7efeba2abfd9c014a22c0f6b3796e0ffb48f5d5ab106568ef01ff5a",
- "sha256:93a71c8601e823236ac0e5d087e4f397874a421017b3318fd92c0b14acf2b6db",
- "sha256:9509c4123491d0e63fb5e16199e09f8e262066e58903e84615c301dde8fa2e87",
- "sha256:a29762cd3d116585278ffb2e5b8cc311fb095ea278b96feef28d0b423154858e",
- "sha256:a62dd5d7cc8626a3634208df458c5fe4f21200d96a74d122c83bc2015b333bc1",
- "sha256:ada603db10bb865bbe591939de854faf2c60f43c9b763e90f653224138f910d9",
- "sha256:aee110e4ef3c528f3abbc3c2018c121e708938adeeff9006428dd7c8555e9b3f",
- "sha256:b76d63495b0508ab9fc23f8152bac63205d2a704cd009a2b0722f4c8e0cba8e0",
- "sha256:c0d8326269dbf944b9201911b0d9f3dc524d64779a07518199a58384c3d37a44",
- "sha256:c41411e192f8d3ea39ea70e0fae48762cd11a2244e03751a98bd3c0ca9a4e936",
- "sha256:c68fe3fcde03920c46697585620135b4ecfdfc1ed23e75cc2c2ae9f8502c10b8",
- "sha256:cb8bea573863762bbf45d1e13f87c2d2fd32cee2dbd50d050f83f87429c9e1ea",
- "sha256:cc32b2990fc34380ec2f6195f33a76b6cdaa9eecf09f0c9404b74fc120aef36f",
- "sha256:ccae5de2a0140d8be6838c331604f91d6fafd0735dbdcee1ac78fc8fbaba76b4",
- "sha256:d299797d75cd747e7797b1b41817111406b8b10a4f88b6e8fe5b5e59598b43b0",
- "sha256:e04b622bb8a88f10e439084486f2f6349bf4d50605ac3e445869c7ea5cf0fa8c",
- "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f",
- "sha256:e21f66748ab725ade40fa7af8ec8b5019c68ab00b929f6643e1b1af461eddb60",
- "sha256:eb60b026d8ad0c97917cb81d3662d0b39b8ff1335e3fabb24984c6acd0c900a2",
- "sha256:f021d334f2ca692523aaf7bbf7592ceff70c8594fad853416a81d66b35e3abf9",
- "sha256:f552023710d4b93d8fb29a91fadf97de89c5926c6bd758897875435f2a939f33"
+ "sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763",
+ "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436",
+ "sha256:07b441f7d03b9a66299ce7ccf3ef2900abc81c0db434f42a5694a37bd73870f2",
+ "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588",
+ "sha256:1e0d612a17581b6616ff03c8e3d5eff7452f34655c901f75d62bd86449d9750e",
+ "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959",
+ "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d",
+ "sha256:28120ef39c92c2dd60f2721af9328479516844c6b550b077ca450c7d7dc68575",
+ "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908",
+ "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8",
+ "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8",
+ "sha256:3d6718667da04294d7df1670d70eeddd414f313738d20a6f1d1f379e3139a545",
+ "sha256:3dbb986bad3ed5ceaf090200eba750b5245150bd97d3e67343a3cfed06feecf7",
+ "sha256:4557e1f11c5f653ebfdd924f3f9d5ebfc718283b0b9beebaa5dd6b77ec290971",
+ "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855",
+ "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c",
+ "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71",
+ "sha256:50aae840ebbd6cdd41af1c14590e5741665e5272d2fee999306673a1bb1fdb4d",
+ "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb",
+ "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72",
+ "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f",
+ "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5",
+ "sha256:6a440293d802d3011028e14e4226da1434b373cbaf4a4bbb63f845761a708346",
+ "sha256:72c28b84b174ce8af8504ca28ae9347d317f9dba3999e5981a3cd441f3712e24",
+ "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e",
+ "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5",
+ "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08",
+ "sha256:8958b10490125124463095bbdadda5aa22ec799f91958e410438ad6c97a7b793",
+ "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88",
+ "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686",
+ "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b",
+ "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2",
+ "sha256:9fe53b404f24789b5ea9003fc25b9a3988feddebd7e7b369c8fac27ad6f52f28",
+ "sha256:a4e46a888b54be23d03a89be510f24a7652fe6ff660787b96cd0e57a4ebcb46d",
+ "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5",
+ "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a",
+ "sha256:af148a33ff0349f53512a049c6406923e4e02bf2f26c5fb285f143faf4f0e46a",
+ "sha256:b11d0cfdd2b095e7b0686cf5fabeb9c67fae5b06d265d8180715b8cfa86522e3",
+ "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf",
+ "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5",
+ "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef",
+ "sha256:b817d41d692bf286abc181f8af476c4fbef3fd05e798777492618378448ee689",
+ "sha256:b81ee3d84803fd42d0b154cb6892ae57ea6b7c55d8359a02379965706c7efe6c",
+ "sha256:be9812b766cad94a25bc63bec11f88c4ad3629a0cec1cd5d4ba48dc23860486b",
+ "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07",
+ "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa",
+ "sha256:c4ae3005ed83f5967f961fd091f2f8c5329161f69ce8480aa8168b2d7fe37f06",
+ "sha256:c54a1e53a0c308a8e8a7dffb59097bff7facda27c70c286f005327f21b2bd6b1",
+ "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff",
+ "sha256:dc022184d3e5cacc9579e41805a681187650e170eb2fd70e28b86192a479dcaa",
+ "sha256:e32092c47011d113dc01ab3e1d3ce9f006a47223b18422c5c0d150af13a00687",
+ "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4",
+ "sha256:f942a799516184c855e1a32fbc7b29d7e571b52612647866d4ec1c3242578fcb",
+ "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44",
+ "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c",
+ "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e",
+ "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53"
],
"markers": "python_version >= '3.7'",
- "version": "==2.0.35"
+ "version": "==2.0.36"
},
"starlette": {
"hashes": [
@@ -2068,19 +2169,19 @@
},
"tqdm": {
"hashes": [
- "sha256:90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd",
- "sha256:e1020aef2e5096702d8a025ac7d16b1577279c9d63f8375b63083e9a5f0fcbad"
+ "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be",
+ "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a"
],
"markers": "python_version >= '3.7'",
- "version": "==4.66.5"
+ "version": "==4.67.0"
},
"typer": {
"hashes": [
- "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b",
- "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722"
+ "sha256:d85fe0b777b2517cc99c8055ed735452f2659cd45e451507c76f48ce5c1d00e2",
+ "sha256:f1c7198347939361eec90139ffa0fd8b3df3a2259d5852a0f7400e476d95985c"
],
"markers": "python_version >= '3.7'",
- "version": "==0.12.5"
+ "version": "==0.13.0"
},
"typing-extensions": {
"hashes": [
@@ -2202,47 +2303,53 @@
"standard"
],
"hashes": [
- "sha256:13bc21373d103859f68fe739608e2eb054a816dea79189bc3ca08ea89a275906",
- "sha256:cac7be4dd4d891c363cd942160a7b02e69150dcbc7a36be04d5f4af4b17c8ced"
+ "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82",
+ "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e"
],
"markers": "python_version >= '3.8'",
- "version": "==0.31.0"
+ "version": "==0.32.0"
},
"uvloop": {
"hashes": [
- "sha256:265a99a2ff41a0fd56c19c3838b29bf54d1d177964c300dad388b27e84fd7847",
- "sha256:2beee18efd33fa6fdb0976e18475a4042cd31c7433c866e8a09ab604c7c22ff2",
- "sha256:35968fc697b0527a06e134999eef859b4034b37aebca537daeb598b9d45a137b",
- "sha256:36c530d8fa03bfa7085af54a48f2ca16ab74df3ec7108a46ba82fd8b411a2315",
- "sha256:3a609780e942d43a275a617c0839d85f95c334bad29c4c0918252085113285b5",
- "sha256:4603ca714a754fc8d9b197e325db25b2ea045385e8a3ad05d3463de725fdf469",
- "sha256:4b75f2950ddb6feed85336412b9a0c310a2edbcf4cf931aa5cfe29034829676d",
- "sha256:4f44af67bf39af25db4c1ac27e82e9665717f9c26af2369c404be865c8818dcf",
- "sha256:6462c95f48e2d8d4c993a2950cd3d31ab061864d1c226bbf0ee2f1a8f36674b9",
- "sha256:649c33034979273fa71aa25d0fe120ad1777c551d8c4cd2c0c9851d88fcb13ab",
- "sha256:746242cd703dc2b37f9d8b9f173749c15e9a918ddb021575a0205ec29a38d31e",
- "sha256:77fbc69c287596880ecec2d4c7a62346bef08b6209749bf6ce8c22bbaca0239e",
- "sha256:80dc1b139516be2077b3e57ce1cb65bfed09149e1d175e0478e7a987863b68f0",
- "sha256:82edbfd3df39fb3d108fc079ebc461330f7c2e33dbd002d146bf7c445ba6e756",
- "sha256:89e8d33bb88d7263f74dc57d69f0063e06b5a5ce50bb9a6b32f5fcbe655f9e73",
- "sha256:94707205efbe809dfa3a0d09c08bef1352f5d3d6612a506f10a319933757c006",
- "sha256:95720bae002ac357202e0d866128eb1ac82545bcf0b549b9abe91b5178d9b541",
- "sha256:9b04d96188d365151d1af41fa2d23257b674e7ead68cfd61c725a422764062ae",
- "sha256:9d0fba61846f294bce41eb44d60d58136090ea2b5b99efd21cbdf4e21927c56a",
- "sha256:9ebafa0b96c62881d5cafa02d9da2e44c23f9f0cd829f3a32a6aff771449c996",
- "sha256:a0fac7be202596c7126146660725157d4813aa29a4cc990fe51346f75ff8fde7",
- "sha256:aea15c78e0d9ad6555ed201344ae36db5c63d428818b4b2a42842b3870127c00",
- "sha256:b10c2956efcecb981bf9cfb8184d27d5d64b9033f917115a960b83f11bfa0d6b",
- "sha256:b16696f10e59d7580979b420eedf6650010a4a9c3bd8113f24a103dfdb770b10",
- "sha256:d8c36fdf3e02cec92aed2d44f63565ad1522a499c654f07935c8f9d04db69e95",
- "sha256:e237f9c1e8a00e7d9ddaa288e535dc337a39bcbf679f290aee9d26df9e72bce9",
- "sha256:e50289c101495e0d1bb0bfcb4a60adde56e32f4449a67216a1ab2750aa84f037",
- "sha256:e7d61fe8e8d9335fac1bf8d5d82820b4808dd7a43020c149b63a1ada953d48a6",
- "sha256:e97152983442b499d7a71e44f29baa75b3b02e65d9c44ba53b10338e98dedb66",
- "sha256:f0e94b221295b5e69de57a1bd4aeb0b3a29f61be6e1b478bb8a69a73377db7ba",
- "sha256:fee6044b64c965c425b65a4e17719953b96e065c5b7e09b599ff332bb2744bdf"
- ],
- "version": "==0.20.0"
+ "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0",
+ "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f",
+ "sha256:10da8046cc4a8f12c91a1c39d1dd1585c41162a15caaef165c2174db9ef18bdc",
+ "sha256:17df489689befc72c39a08359efac29bbee8eee5209650d4b9f34df73d22e414",
+ "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f",
+ "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d",
+ "sha256:221f4f2a1f46032b403bf3be628011caf75428ee3cc204a22addf96f586b19fd",
+ "sha256:2d1f581393673ce119355d56da84fe1dd9d2bb8b3d13ce792524e1607139feff",
+ "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c",
+ "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3",
+ "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d",
+ "sha256:460def4412e473896ef179a1671b40c039c7012184b627898eea5072ef6f017a",
+ "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb",
+ "sha256:46923b0b5ee7fc0020bef24afe7836cb068f5050ca04caf6b487c513dc1a20b2",
+ "sha256:53e420a3afe22cdcf2a0f4846e377d16e718bc70103d7088a4f7623567ba5fb0",
+ "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6",
+ "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c",
+ "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af",
+ "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc",
+ "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb",
+ "sha256:88cb67cdbc0e483da00af0b2c3cdad4b7c61ceb1ee0f33fe00e09c81e3a6cb75",
+ "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb",
+ "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553",
+ "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e",
+ "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6",
+ "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d",
+ "sha256:bc09f0ff191e61c2d592a752423c767b4ebb2986daa9ed62908e2b1b9a9ae206",
+ "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc",
+ "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281",
+ "sha256:c097078b8031190c934ed0ebfee8cc5f9ba9642e6eb88322b9958b649750f72b",
+ "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8",
+ "sha256:e678ad6fe52af2c58d2ae3c73dc85524ba8abe637f134bf3564ed07f555c5e79",
+ "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f",
+ "sha256:f0ce1b49560b1d2d8a2977e3ba4afb2414fb46b86a1b64056bc4ab929efdafbe",
+ "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26",
+ "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816",
+ "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2"
+ ],
+ "version": "==0.21.0"
},
"watchfiles": {
"hashes": [
@@ -2334,94 +2441,77 @@
},
"websockets": {
"hashes": [
- "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a",
- "sha256:035233b7531fb92a76beefcbf479504db8c72eb3bff41da55aecce3a0f729e54",
- "sha256:149e622dc48c10ccc3d2760e5f36753db9cacf3ad7bc7bbbfd7d9c819e286f23",
- "sha256:163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7",
- "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135",
- "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700",
- "sha256:204e5107f43095012b00f1451374693267adbb832d29966a01ecc4ce1db26faf",
- "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5",
- "sha256:25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e",
- "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c",
- "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02",
- "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a",
- "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418",
- "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f",
- "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3",
- "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68",
- "sha256:4059f790b6ae8768471cddb65d3c4fe4792b0ab48e154c9f0a04cefaabcd5978",
- "sha256:459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20",
- "sha256:463e1c6ec853202dd3657f156123d6b4dad0c546ea2e2e38be2b3f7c5b8e7295",
- "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b",
- "sha256:485307243237328c022bc908b90e4457d0daa8b5cf4b3723fd3c4a8012fce4c6",
- "sha256:48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb",
- "sha256:4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a",
- "sha256:586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa",
- "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0",
- "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a",
- "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238",
- "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c",
- "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084",
- "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19",
- "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d",
- "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7",
- "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9",
- "sha256:6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79",
- "sha256:6d6855bbe70119872c05107e38fbc7f96b1d8cb047d95c2c50869a46c65a8e96",
- "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6",
- "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe",
- "sha256:7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842",
- "sha256:7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa",
- "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3",
- "sha256:7c65ffa900e7cc958cd088b9a9157a8141c991f8c53d11087e6fb7277a03f81d",
- "sha256:80c421e07973a89fbdd93e6f2003c17d20b69010458d3a8e37fb47874bd67d51",
- "sha256:82d0ba76371769d6a4e56f7e83bb8e81846d17a6190971e38b5de108bde9b0d7",
- "sha256:83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09",
- "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096",
- "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9",
- "sha256:9156c45750b37337f7b0b00e6248991a047be4aa44554c9886fe6bdd605aab3b",
- "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5",
- "sha256:95858ca14a9f6fa8413d29e0a585b31b278388aa775b8a81fa24830123874678",
- "sha256:95df24ca1e1bd93bbca51d94dd049a984609687cb2fb08a7f2c56ac84e9816ea",
- "sha256:9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d",
- "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49",
- "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc",
- "sha256:9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5",
- "sha256:a11e38ad8922c7961447f35c7b17bffa15de4d17c70abd07bfbe12d6faa3e027",
- "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0",
- "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878",
- "sha256:a569eb1b05d72f9bce2ebd28a1ce2054311b66677fcd46cf36204ad23acead8c",
- "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa",
- "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f",
- "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6",
- "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2",
- "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf",
- "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708",
- "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6",
- "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f",
- "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd",
- "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2",
- "sha256:c7934fd0e920e70468e676fe7f1b7261c1efa0d6c037c6722278ca0228ad9d0d",
- "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7",
- "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f",
- "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5",
- "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6",
- "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557",
- "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14",
- "sha256:d8dbb1bf0c0a4ae8b40bdc9be7f644e2f3fb4e8a9aca7145bfa510d4a374eeb7",
- "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd",
- "sha256:deeb929efe52bed518f6eb2ddc00cc496366a14c726005726ad62c2dd9017a3c",
- "sha256:df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17",
- "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23",
- "sha256:e4450fc83a3df53dec45922b576e91e94f5578d06436871dce3a6be38e40f5db",
- "sha256:e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6",
- "sha256:e9875a0143f07d74dc5e1ded1c4581f0d9f7ab86c78994e2ed9e95050073c94d",
- "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9",
- "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee",
- "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6"
- ],
- "version": "==13.1"
+ "sha256:00fe5da3f037041da1ee0cf8e308374e236883f9842c7c465aa65098b1c9af59",
+ "sha256:01bb2d4f0a6d04538d3c5dfd27c0643269656c28045a53439cbf1c004f90897a",
+ "sha256:034feb9f4286476f273b9a245fb15f02c34d9586a5bc936aff108c3ba1b21beb",
+ "sha256:04a97aca96ca2acedf0d1f332c861c5a4486fdcba7bcef35873820f940c4231e",
+ "sha256:0d4290d559d68288da9f444089fd82490c8d2744309113fc26e2da6e48b65da6",
+ "sha256:1288369a6a84e81b90da5dbed48610cd7e5d60af62df9851ed1d1d23a9069f10",
+ "sha256:14839f54786987ccd9d03ed7f334baec0f02272e7ec4f6e9d427ff584aeea8b4",
+ "sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0",
+ "sha256:1f874ba705deea77bcf64a9da42c1f5fc2466d8f14daf410bc7d4ceae0a9fcb0",
+ "sha256:205f672a6c2c671a86d33f6d47c9b35781a998728d2c7c2a3e1cf3333fcb62b7",
+ "sha256:2177ee3901075167f01c5e335a6685e71b162a54a89a56001f1c3e9e3d2ad250",
+ "sha256:219c8187b3ceeadbf2afcf0f25a4918d02da7b944d703b97d12fb01510869078",
+ "sha256:25225cc79cfebc95ba1d24cd3ab86aaa35bcd315d12fa4358939bd55e9bd74a5",
+ "sha256:3630b670d5057cd9e08b9c4dab6493670e8e762a24c2c94ef312783870736ab9",
+ "sha256:368a05465f49c5949e27afd6fbe0a77ce53082185bbb2ac096a3a8afaf4de52e",
+ "sha256:36ebd71db3b89e1f7b1a5deaa341a654852c3518ea7a8ddfdf69cc66acc2db1b",
+ "sha256:39450e6215f7d9f6f7bc2a6da21d79374729f5d052333da4d5825af8a97e6735",
+ "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8",
+ "sha256:3c3deac3748ec73ef24fc7be0b68220d14d47d6647d2f85b2771cb35ea847aa1",
+ "sha256:3f14a96a0034a27f9d47fd9788913924c89612225878f8078bb9d55f859272b0",
+ "sha256:3fc753451d471cff90b8f467a1fc0ae64031cf2d81b7b34e1811b7e2691bc4bc",
+ "sha256:414ffe86f4d6f434a8c3b7913655a1a5383b617f9bf38720e7c0799fac3ab1c6",
+ "sha256:449d77d636f8d9c17952628cc7e3b8faf6e92a17ec581ec0c0256300717e1512",
+ "sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4",
+ "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e",
+ "sha256:5a42d3ecbb2db5080fc578314439b1d79eef71d323dc661aa616fb492436af5d",
+ "sha256:5b918d288958dc3fa1c5a0b9aa3256cb2b2b84c54407f4813c45d52267600cd3",
+ "sha256:5ef440054124728cc49b01c33469de06755e5a7a4e83ef61934ad95fc327fbb0",
+ "sha256:660c308dabd2b380807ab64b62985eaccf923a78ebc572bd485375b9ca2b7dc7",
+ "sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058",
+ "sha256:6d24fc337fc055c9e83414c94e1ee0dee902a486d19d2a7f0929e49d7d604b09",
+ "sha256:7048eb4415d46368ef29d32133134c513f507fff7d953c18c91104738a68c3b3",
+ "sha256:77569d19a13015e840b81550922056acabc25e3f52782625bc6843cfa034e1da",
+ "sha256:8149a0f5a72ca36720981418eeffeb5c2729ea55fa179091c81a0910a114a5d2",
+ "sha256:836bef7ae338a072e9d1863502026f01b14027250a4545672673057997d5c05a",
+ "sha256:8621a07991add373c3c5c2cf89e1d277e49dc82ed72c75e3afc74bd0acc446f0",
+ "sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d",
+ "sha256:88cf9163ef674b5be5736a584c999e98daf3aabac6e536e43286eb74c126b9c7",
+ "sha256:8fda642151d5affdee8a430bd85496f2e2517be3a2b9d2484d633d5712b15c56",
+ "sha256:90b5d9dfbb6d07a84ed3e696012610b6da074d97453bd01e0e30744b472c8179",
+ "sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f",
+ "sha256:9481a6de29105d73cf4515f2bef8eb71e17ac184c19d0b9918a3701c6c9c4f23",
+ "sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199",
+ "sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a",
+ "sha256:a032855dc7db987dff813583d04f4950d14326665d7e714d584560b140ae6b8b",
+ "sha256:a0adf84bc2e7c86e8a202537b4fd50e6f7f0e4a6b6bf64d7ccb96c4cd3330b29",
+ "sha256:a35f704be14768cea9790d921c2c1cc4fc52700410b1c10948511039be824aac",
+ "sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58",
+ "sha256:a4c805c6034206143fbabd2d259ec5e757f8b29d0a2f0bf3d2fe5d1f60147a4a",
+ "sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45",
+ "sha256:ad2ab2547761d79926effe63de21479dfaf29834c50f98c4bf5b5480b5838434",
+ "sha256:b1f3628a0510bd58968c0f60447e7a692933589b791a6b572fcef374053ca280",
+ "sha256:b7e7ea2f782408c32d86b87a0d2c1fd8871b0399dd762364c731d86c86069a78",
+ "sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707",
+ "sha256:bea45f19b7ca000380fbd4e02552be86343080120d074b87f25593ce1700ad58",
+ "sha256:cc1fc87428c1d18b643479caa7b15db7d544652e5bf610513d4a3478dbe823d0",
+ "sha256:cd7c11968bc3860d5c78577f0dbc535257ccec41750675d58d8dc66aa47fe52c",
+ "sha256:ceada5be22fa5a5a4cdeec74e761c2ee7db287208f54c718f2df4b7e200b8d4a",
+ "sha256:cf5201a04550136ef870aa60ad3d29d2a59e452a7f96b94193bee6d73b8ad9a9",
+ "sha256:d9fd19ecc3a4d5ae82ddbfb30962cf6d874ff943e56e0c81f5169be2fda62979",
+ "sha256:ddaa4a390af911da6f680be8be4ff5aaf31c4c834c1a9147bc21cbcbca2d4370",
+ "sha256:df174ece723b228d3e8734a6f2a6febbd413ddec39b3dc592f5a4aa0aff28098",
+ "sha256:e0744623852f1497d825a49a99bfbec9bea4f3f946df6eb9d8a2f0c37a2fec2e",
+ "sha256:e5dc25a9dbd1a7f61eca4b7cb04e74ae4b963d658f9e4f9aad9cd00b688692c8",
+ "sha256:e7591d6f440af7f73c4bd9404f3772bfee064e639d2b6cc8c94076e71b2471c1",
+ "sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05",
+ "sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed",
+ "sha256:f6cf0ad281c979306a6a34242b371e90e891bce504509fb6bb5246bbbf31e7b6",
+ "sha256:f95ba34d71e2fa0c5d225bde3b3bdb152e957150100e75c86bc7f3964c450d89"
+ ],
+ "version": "==14.1"
},
"wrapt": {
"hashes": [
@@ -2501,117 +2591,107 @@
},
"xmltodict": {
"hashes": [
- "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56",
- "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"
+ "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553",
+ "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"
],
- "markers": "python_version >= '3.4'",
- "version": "==0.13.0"
+ "markers": "python_version >= '3.6'",
+ "version": "==0.14.2"
},
"yarl": {
"hashes": [
- "sha256:047b258e00b99091b6f90355521f026238c63bd76dcf996d93527bb13320eefd",
- "sha256:06ff23462398333c78b6f4f8d3d70410d657a471c2c5bbe6086133be43fc8f1a",
- "sha256:07f9eaf57719d6721ab15805d85f4b01a5b509a0868d7320134371bcb652152d",
- "sha256:0aa92e3e30a04f9462a25077db689c4ac5ea9ab6cc68a2e563881b987d42f16d",
- "sha256:0cf21f46a15d445417de8fc89f2568852cf57fe8ca1ab3d19ddb24d45c0383ae",
- "sha256:0fd7b941dd1b00b5f0acb97455fea2c4b7aac2dd31ea43fb9d155e9bc7b78664",
- "sha256:147e36331f6f63e08a14640acf12369e041e0751bb70d9362df68c2d9dcf0c87",
- "sha256:16a682a127930f3fc4e42583becca6049e1d7214bcad23520c590edd741d2114",
- "sha256:176110bff341b6730f64a1eb3a7070e12b373cf1c910a9337e7c3240497db76f",
- "sha256:19268b4fec1d7760134f2de46ef2608c2920134fb1fa61e451f679e41356dc55",
- "sha256:1b16f6c75cffc2dc0616ea295abb0e1967601bd1fb1e0af6a1de1c6c887f3439",
- "sha256:1bfc25aa6a7c99cf86564210f79a0b7d4484159c67e01232b116e445b3036547",
- "sha256:1ca3894e9e9f72da93544f64988d9c052254a338a9f855165f37f51edb6591de",
- "sha256:1dda53508df0de87b6e6b0a52d6718ff6c62a5aca8f5552748404963df639269",
- "sha256:217a782020b875538eebf3948fac3a7f9bbbd0fd9bf8538f7c2ad7489e80f4e8",
- "sha256:2192f718db4a8509f63dd6d950f143279211fa7e6a2c612edc17d85bf043d36e",
- "sha256:29a84a46ec3ebae7a1c024c055612b11e9363a8a23238b3e905552d77a2bc51b",
- "sha256:3007a5b75cb50140708420fe688c393e71139324df599434633019314ceb8b59",
- "sha256:30600ba5db60f7c0820ef38a2568bb7379e1418ecc947a0f76fd8b2ff4257a97",
- "sha256:337912bcdcf193ade64b9aae5a4017a0a1950caf8ca140362e361543c6773f21",
- "sha256:37001e5d4621cef710c8dc1429ca04e189e572f128ab12312eab4e04cf007132",
- "sha256:3d569f877ed9a708e4c71a2d13d2940cb0791da309f70bd970ac1a5c088a0a92",
- "sha256:4009def9be3a7e5175db20aa2d7307ecd00bbf50f7f0f989300710eee1d0b0b9",
- "sha256:46a9772a1efa93f9cd170ad33101c1817c77e0e9914d4fe33e2da299d7cf0f9b",
- "sha256:47eede5d11d669ab3759b63afb70d28d5328c14744b8edba3323e27dc52d298d",
- "sha256:498b3c55087b9d762636bca9b45f60d37e51d24341786dc01b81253f9552a607",
- "sha256:4e0d45ebf975634468682c8bec021618b3ad52c37619e5c938f8f831fa1ac5c0",
- "sha256:4f24f08b6c9b9818fd80612c97857d28f9779f0d1211653ece9844fc7b414df2",
- "sha256:55c144d363ad4626ca744556c049c94e2b95096041ac87098bb363dcc8635e8d",
- "sha256:582cedde49603f139be572252a318b30dc41039bc0b8165f070f279e5d12187f",
- "sha256:587c3cc59bc148a9b1c07a019346eda2549bc9f468acd2f9824d185749acf0a6",
- "sha256:5cd5dad8366e0168e0fd23d10705a603790484a6dbb9eb272b33673b8f2cce72",
- "sha256:5d02d700705d67e09e1f57681f758f0b9d4412eeb70b2eb8d96ca6200b486db3",
- "sha256:625f207b1799e95e7c823f42f473c1e9dbfb6192bd56bba8695656d92be4535f",
- "sha256:659603d26d40dd4463200df9bfbc339fbfaed3fe32e5c432fe1dc2b5d4aa94b4",
- "sha256:689a99a42ee4583fcb0d3a67a0204664aa1539684aed72bdafcbd505197a91c4",
- "sha256:68ac1a09392ed6e3fd14be880d39b951d7b981fd135416db7d18a6208c536561",
- "sha256:6a615cad11ec3428020fb3c5a88d85ce1b5c69fd66e9fcb91a7daa5e855325dd",
- "sha256:73bedd2be05f48af19f0f2e9e1353921ce0c83f4a1c9e8556ecdcf1f1eae4892",
- "sha256:742aef0a99844faaac200564ea6f5e08facb285d37ea18bd1a5acf2771f3255a",
- "sha256:75ff4c819757f9bdb35de049a509814d6ce851fe26f06eb95a392a5640052482",
- "sha256:781e2495e408a81e4eaeedeb41ba32b63b1980dddf8b60dbbeff6036bcd35049",
- "sha256:7a9f917966d27f7ce30039fe8d900f913c5304134096554fd9bea0774bcda6d1",
- "sha256:7e2637d75e92763d1322cb5041573279ec43a80c0f7fbbd2d64f5aee98447b17",
- "sha256:8089d4634d8fa2b1806ce44fefa4979b1ab2c12c0bc7ef3dfa45c8a374811348",
- "sha256:816d24f584edefcc5ca63428f0b38fee00b39fe64e3c5e558f895a18983efe96",
- "sha256:8385ab36bf812e9d37cf7613999a87715f27ef67a53f0687d28c44b819df7cb0",
- "sha256:85cb3e40eaa98489f1e2e8b29f5ad02ee1ee40d6ce6b88d50cf0f205de1d9d2c",
- "sha256:8648180b34faaea4aa5b5ca7e871d9eb1277033fa439693855cf0ea9195f85f1",
- "sha256:8892fa575ac9b1b25fae7b221bc4792a273877b9b56a99ee2d8d03eeb3dbb1d2",
- "sha256:88c7d9d58aab0724b979ab5617330acb1c7030b79379c8138c1c8c94e121d1b3",
- "sha256:8a2f8fb7f944bcdfecd4e8d855f84c703804a594da5123dd206f75036e536d4d",
- "sha256:8f4e475f29a9122f908d0f1f706e1f2fc3656536ffd21014ff8a6f2e1b14d1d8",
- "sha256:8f50eb3837012a937a2b649ec872b66ba9541ad9d6f103ddcafb8231cfcafd22",
- "sha256:91d875f75fabf76b3018c5f196bf3d308ed2b49ddcb46c1576d6b075754a1393",
- "sha256:94b2bb9bcfd5be9d27004ea4398fb640373dd0c1a9e219084f42c08f77a720ab",
- "sha256:9557c9322aaa33174d285b0c1961fb32499d65ad1866155b7845edc876c3c835",
- "sha256:95e16e9eaa2d7f5d87421b8fe694dd71606aa61d74b824c8d17fc85cc51983d1",
- "sha256:96952f642ac69075e44c7d0284528938fdff39422a1d90d3e45ce40b72e5e2d9",
- "sha256:985623575e5c4ea763056ffe0e2d63836f771a8c294b3de06d09480538316b13",
- "sha256:99ff3744f5fe48288be6bc402533b38e89749623a43208e1d57091fc96b783b9",
- "sha256:9abe80ae2c9d37c17599557b712e6515f4100a80efb2cda15f5f070306477cd2",
- "sha256:a152751af7ef7b5d5fa6d215756e508dd05eb07d0cf2ba51f3e740076aa74373",
- "sha256:a2e4725a08cb2b4794db09e350c86dee18202bb8286527210e13a1514dc9a59a",
- "sha256:a56fbe3d7f3bce1d060ea18d2413a2ca9ca814eea7cedc4d247b5f338d54844e",
- "sha256:ab3abc0b78a5dfaa4795a6afbe7b282b6aa88d81cf8c1bb5e394993d7cae3457",
- "sha256:b03384eed107dbeb5f625a99dc3a7de8be04fc8480c9ad42fccbc73434170b20",
- "sha256:b0547ab1e9345dc468cac8368d88ea4c5bd473ebc1d8d755347d7401982b5dd8",
- "sha256:b4c1ecba93e7826dc71ddba75fb7740cdb52e7bd0be9f03136b83f54e6a1f511",
- "sha256:b693c63e7e64b524f54aa4888403c680342d1ad0d97be1707c531584d6aeeb4f",
- "sha256:b6d0147574ce2e7b812c989e50fa72bbc5338045411a836bd066ce5fc8ac0bce",
- "sha256:b9cfef3f14f75bf6aba73a76caf61f9d00865912a04a4393c468a7ce0981b519",
- "sha256:b9f805e37ed16cc212fdc538a608422d7517e7faf539bedea4fe69425bc55d76",
- "sha256:bab03192091681d54e8225c53f270b0517637915d9297028409a2a5114ff4634",
- "sha256:bc24f968b82455f336b79bf37dbb243b7d76cd40897489888d663d4e028f5069",
- "sha256:c14b504a74e58e2deb0378b3eca10f3d076635c100f45b113c18c770b4a47a50",
- "sha256:c2089a9afef887664115f7fa6d3c0edd6454adaca5488dba836ca91f60401075",
- "sha256:c8ed4034f0765f8861620c1f2f2364d2e58520ea288497084dae880424fc0d9f",
- "sha256:cd2660c01367eb3ef081b8fa0a5da7fe767f9427aa82023a961a5f28f0d4af6c",
- "sha256:d8361c7d04e6a264481f0b802e395f647cd3f8bbe27acfa7c12049efea675bd1",
- "sha256:d9baec588f015d0ee564057aa7574313c53a530662ffad930b7886becc85abdf",
- "sha256:dbd9ff43a04f8ffe8a959a944c2dca10d22f5f99fc6a459f49c3ebfb409309d9",
- "sha256:e3f8bfc1db82589ef965ed234b87de30d140db8b6dc50ada9e33951ccd8ec07a",
- "sha256:e6a2c5c5bb2556dfbfffffc2bcfb9c235fd2b566d5006dfb2a37afc7e3278a07",
- "sha256:e749af6c912a7bb441d105c50c1a3da720474e8acb91c89350080dd600228f0e",
- "sha256:e85d86527baebb41a214cc3b45c17177177d900a2ad5783dbe6f291642d4906f",
- "sha256:ee2c68e4f2dd1b1c15b849ba1c96fac105fca6ffdb7c1e8be51da6fabbdeafb9",
- "sha256:f3ab950f8814f3b7b5e3eebc117986f817ec933676f68f0a6c5b2137dd7c9c69",
- "sha256:f4f4547944d4f5cfcdc03f3f097d6f05bbbc915eaaf80a2ee120d0e756de377d",
- "sha256:f72a0d746d38cb299b79ce3d4d60ba0892c84bbc905d0d49c13df5bace1b65f8",
- "sha256:fc2c80bc87fba076e6cbb926216c27fba274dae7100a7b9a0983b53132dd99f2",
- "sha256:fe4d2536c827f508348d7b40c08767e8c7071614250927233bf0c92170451c0a"
- ],
- "markers": "python_version >= '3.8'",
- "version": "==1.14.0"
+ "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac",
+ "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47",
+ "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91",
+ "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5",
+ "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df",
+ "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3",
+ "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463",
+ "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b",
+ "sha256:1a3b91c44efa29e6c8ef8a9a2b583347998e2ba52c5d8280dbd5919c02dfc3b5",
+ "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74",
+ "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3",
+ "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3",
+ "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4",
+ "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0",
+ "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299",
+ "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2",
+ "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac",
+ "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61",
+ "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931",
+ "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21",
+ "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3",
+ "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7",
+ "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96",
+ "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f",
+ "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243",
+ "sha256:578d00c9b7fccfa1745a44f4eddfdc99d723d157dad26764538fbdda37209857",
+ "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f",
+ "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca",
+ "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488",
+ "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da",
+ "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948",
+ "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5",
+ "sha256:6f4c9156c4d1eb490fe374fb294deeb7bc7eaccda50e23775b2354b6a6739934",
+ "sha256:7294e38f9aa2e9f05f765b28ffdc5d81378508ce6dadbe93f6d464a8c9594473",
+ "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7",
+ "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685",
+ "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e",
+ "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147",
+ "sha256:7fac95714b09da9278a0b52e492466f773cfe37651cf467a83a1b659be24bf71",
+ "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67",
+ "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04",
+ "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822",
+ "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11",
+ "sha256:8994b29c462de9a8fce2d591028b986dbbe1b32f3ad600b2d3e1c482c93abad6",
+ "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0",
+ "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec",
+ "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda",
+ "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556",
+ "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4",
+ "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c",
+ "sha256:a7ac5b4984c468ce4f4a553df281450df0a34aefae02e58d77a0847be8d1e11f",
+ "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8",
+ "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba",
+ "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258",
+ "sha256:b40d1bf6e6f74f7c0a567a9e5e778bbd4699d1d3d2c0fe46f4b717eef9e96b95",
+ "sha256:b5c4804e4039f487e942c13381e6c27b4b4e66066d94ef1fae3f6ba8b953f383",
+ "sha256:b5d6a6c9602fd4598fa07e0389e19fe199ae96449008d8304bf5d47cb745462e",
+ "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938",
+ "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374",
+ "sha256:c180ac742a083e109c1a18151f4dd8675f32679985a1c750d2ff806796165b55",
+ "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139",
+ "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17",
+ "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217",
+ "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d",
+ "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d",
+ "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe",
+ "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199",
+ "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d",
+ "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8",
+ "sha256:d6324274b4e0e2fa1b3eccb25997b1c9ed134ff61d296448ab8269f5ac068c4c",
+ "sha256:d8a8b74d843c2638f3864a17d97a4acda58e40d3e44b6303b8cc3d3c44ae2d29",
+ "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172",
+ "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860",
+ "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7",
+ "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170",
+ "sha256:eb6dce402734575e1a8cc0bb1509afca508a400a57ce13d306ea2c663bad1138",
+ "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06",
+ "sha256:f5efe0661b9fcd6246f27957f6ae1c0eb29bc60552820f01e970b4996e016004",
+ "sha256:f9cbfbc5faca235fbdf531b93aa0f9f005ec7d267d9d738761a4d42b744ea159",
+ "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da",
+ "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988",
+ "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==1.17.1"
},
"zipp": {
"hashes": [
- "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350",
- "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"
+ "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4",
+ "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"
],
- "markers": "python_version >= '3.8'",
- "version": "==3.20.2"
+ "markers": "python_version >= '3.9'",
+ "version": "==3.21.0"
}
},
"develop": {
@@ -2672,11 +2752,11 @@
},
"botocore-stubs": {
"hashes": [
- "sha256:b1aebecdfa4f4fc02b0a68a5e438877034b195168809a7202ee32b42245d3ece",
- "sha256:d79a408dfc503a1a0389d10cd29ad22a01450d0d53902ea216815e2ba98913ba"
+ "sha256:1456af3358be1a0e49dd8428bfb81863406659d9fad871362bf18a098eeac90a",
+ "sha256:dd83003963ca957a6e4835d192d7f163fb55312ce3d3f798f625ac9438616e4f"
],
"markers": "python_version >= '3.8'",
- "version": "==1.35.35"
+ "version": "==1.35.59"
},
"certifi": {
"hashes": [
@@ -2761,99 +2841,114 @@
},
"charset-normalizer": {
"hashes": [
- "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027",
- "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087",
- "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786",
- "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8",
- "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09",
- "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185",
- "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574",
- "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e",
- "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519",
- "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898",
- "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269",
- "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3",
- "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f",
- "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6",
- "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8",
- "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a",
- "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73",
- "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc",
- "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714",
- "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2",
- "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc",
- "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce",
- "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d",
- "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e",
- "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6",
- "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269",
- "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96",
- "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d",
- "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a",
- "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4",
- "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77",
- "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d",
- "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0",
- "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed",
- "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068",
- "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac",
- "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25",
- "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8",
- "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab",
- "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26",
- "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2",
- "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db",
- "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f",
- "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5",
- "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99",
- "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c",
- "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d",
- "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811",
- "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa",
- "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a",
- "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03",
- "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b",
- "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04",
- "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c",
- "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001",
- "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458",
- "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389",
- "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99",
- "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985",
- "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537",
- "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238",
- "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f",
- "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d",
- "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796",
- "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a",
- "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143",
- "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8",
- "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c",
- "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5",
- "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5",
- "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711",
- "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4",
- "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6",
- "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c",
- "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7",
- "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4",
- "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b",
- "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae",
- "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12",
- "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c",
- "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae",
- "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8",
- "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887",
- "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b",
- "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4",
- "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f",
- "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5",
- "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33",
- "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
- "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
+ "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621",
+ "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6",
+ "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8",
+ "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912",
+ "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c",
+ "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b",
+ "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d",
+ "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d",
+ "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95",
+ "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e",
+ "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565",
+ "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64",
+ "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab",
+ "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be",
+ "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e",
+ "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907",
+ "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0",
+ "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2",
+ "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62",
+ "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62",
+ "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23",
+ "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc",
+ "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284",
+ "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca",
+ "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455",
+ "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858",
+ "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b",
+ "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594",
+ "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc",
+ "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db",
+ "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b",
+ "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea",
+ "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6",
+ "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920",
+ "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749",
+ "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7",
+ "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd",
+ "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99",
+ "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242",
+ "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee",
+ "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129",
+ "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2",
+ "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51",
+ "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee",
+ "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8",
+ "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b",
+ "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613",
+ "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742",
+ "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe",
+ "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3",
+ "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5",
+ "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631",
+ "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7",
+ "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15",
+ "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c",
+ "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea",
+ "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417",
+ "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250",
+ "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88",
+ "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca",
+ "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa",
+ "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99",
+ "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149",
+ "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41",
+ "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574",
+ "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0",
+ "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f",
+ "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d",
+ "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654",
+ "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3",
+ "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19",
+ "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90",
+ "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578",
+ "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9",
+ "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1",
+ "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51",
+ "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719",
+ "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236",
+ "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a",
+ "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c",
+ "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade",
+ "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944",
+ "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc",
+ "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6",
+ "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6",
+ "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27",
+ "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6",
+ "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2",
+ "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12",
+ "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf",
+ "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114",
+ "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7",
+ "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf",
+ "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d",
+ "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b",
+ "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed",
+ "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03",
+ "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4",
+ "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67",
+ "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365",
+ "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a",
+ "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748",
+ "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b",
+ "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079",
+ "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"
],
"markers": "python_full_version >= '3.7.0'",
- "version": "==3.3.2"
+ "version": "==3.4.0"
},
"click": {
"hashes": [
@@ -2865,35 +2960,35 @@
},
"cryptography": {
"hashes": [
- "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494",
- "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806",
- "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d",
- "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062",
- "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2",
- "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4",
- "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1",
- "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85",
- "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84",
- "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042",
- "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d",
- "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962",
- "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2",
- "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa",
- "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d",
- "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365",
- "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96",
- "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47",
- "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d",
- "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d",
- "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c",
- "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb",
- "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277",
- "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172",
- "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034",
- "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a",
- "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"
- ],
- "version": "==43.0.1"
+ "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362",
+ "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4",
+ "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa",
+ "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83",
+ "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff",
+ "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805",
+ "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6",
+ "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664",
+ "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08",
+ "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e",
+ "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18",
+ "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f",
+ "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73",
+ "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5",
+ "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984",
+ "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd",
+ "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3",
+ "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e",
+ "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405",
+ "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2",
+ "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c",
+ "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995",
+ "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73",
+ "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16",
+ "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7",
+ "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd",
+ "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"
+ ],
+ "version": "==43.0.3"
},
"docker": {
"hashes": [
@@ -2988,11 +3083,11 @@
},
"packaging": {
"hashes": [
- "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
- "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
+ "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759",
+ "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"
],
"markers": "python_version >= '3.8'",
- "version": "==24.1"
+ "version": "==24.2"
},
"pathspec": {
"hashes": [
@@ -3061,11 +3156,11 @@
},
"rich": {
"hashes": [
- "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c",
- "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"
+ "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098",
+ "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"
],
"markers": "python_full_version >= '3.8.0'",
- "version": "==13.9.2"
+ "version": "==13.9.4"
},
"ruff": {
"hashes": [
@@ -3093,11 +3188,11 @@
},
"s3transfer": {
"hashes": [
- "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6",
- "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"
+ "sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d",
+ "sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c"
],
"markers": "python_version >= '3.8'",
- "version": "==0.10.2"
+ "version": "==0.10.3"
},
"six": {
"hashes": [
@@ -3109,20 +3204,20 @@
},
"types-awscrt": {
"hashes": [
- "sha256:67a660c90bad360c339f6a79310cc17094d12472042c7ca5a41450aaf5fc9a54",
- "sha256:b2c196bbd3226bab42d80fae13c34548de9ddc195f5a366d79c15d18e5897aa9"
+ "sha256:3fd1edeac923d1956c0e907c973fb83bda465beae7f054716b371b293f9b5fdc",
+ "sha256:517d9d06f19cf58d778ca90ad01e52e0489466bf70dcf78c7f47f74fdf151a60"
],
"markers": "python_version >= '3.8'",
- "version": "==0.22.0"
+ "version": "==0.23.0"
},
"types-beautifulsoup4": {
"hashes": [
- "sha256:32f5ac48514b488f15241afdd7d2f73f0baf3c54e874e23b66708503dd288489",
- "sha256:8d023b86530922070417a1d4c4d91678ab0ff2439b3b2b2cffa3b628b49ebab1"
+ "sha256:158370d08d0cd448bd11b132a50ff5279237a5d4b5837beba074de152a513059",
+ "sha256:c95e66ce15a4f5f0835f7fbc5cd886321ae8294f977c495424eaf4225307fd30"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.12.0.20240907"
+ "version": "==4.12.0.20241020"
},
"types-docker": {
"hashes": [
@@ -3135,28 +3230,28 @@
},
"types-html5lib": {
"hashes": [
- "sha256:575c4fd84ba8eeeaa8520c7e4c7042b7791f5ec3e9c0a5d5c418124c42d9e7e4",
- "sha256:8060dc98baf63d6796a765bbbc809fff9f7a383f6e3a9add526f814c086545ef"
+ "sha256:3f1e064d9ed2c289001ae6392c84c93833abb0816165c6ff0abfc304a779f403",
+ "sha256:98042555ff78d9e3a51c77c918b1041acbb7eb6c405408d8a9e150ff5beccafa"
],
"markers": "python_version >= '3.8'",
- "version": "==1.1.11.20240806"
+ "version": "==1.1.11.20241018"
},
"types-requests": {
"hashes": [
- "sha256:2850e178db3919d9bf809e434eef65ba49d0e7e33ac92d588f4a5e295fffd405",
- "sha256:59c2f673eb55f32a99b2894faf6020e1a9f4a402ad0f192bfee0b64469054310"
+ "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95",
+ "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==2.32.0.20240914"
+ "version": "==2.32.0.20241016"
},
"types-s3transfer": {
"hashes": [
- "sha256:60167a3bfb5c536ec6cdb5818f7f9a28edca9dc3e0b5ff85ae374526fc5e576e",
- "sha256:7a3fec8cd632e2b5efb665a355ef93c2a87fdd5a45b74a949f95a9e628a86356"
+ "sha256:d34c5a82f531af95bb550927136ff5b737a1ed3087f90a59d545591dfde5b4cc",
+ "sha256:f761b2876ac4c208e6c6b75cdf5f6939009768be9950c545b11b0225e7703ee7"
],
"markers": "python_version >= '3.8'",
- "version": "==0.10.2"
+ "version": "==0.10.3"
},
"typing-extensions": {
"hashes": [
diff --git a/opentrons-ai-server/README.md b/opentrons-ai-server/README.md
index b072429c41c..041328a5c99 100644
--- a/opentrons-ai-server/README.md
+++ b/opentrons-ai-server/README.md
@@ -60,6 +60,15 @@ In the deployed environments the FastAPI server is run in a docker container. To
Now the API is running at
View the API docs in a browser at
+##### Docker shell
+
+1. make clean
+1. make build
+1. make run-shell
+1. make shell
+
+Now you are in the docker container and can inspect the environment and such.
+
#### Direct API Interaction and Authentication
> There is only 1 endpoint with the potential to call the OpenAI API. This is the `/api/chat/completion` endpoint. This endpoint requires authentication and the steps are outlined below. In the POST request body setting `"fake": true` will short circuit the handling of the call. The OpenAI API will not be hit. Instead, a hard coded response is returned. We plan to extend this capability to allow for live local testing of the UI without calling the OpenAI API.
@@ -117,3 +126,48 @@ The live-test target will run tests against any environment. The default is loca
1. alter the `Pipfile` to the new pinned version
1. run `make setup` to update the `Pipfile.lock`
+
+## Google Sheets Integration
+
+1. Create a Google Cloud Platform project
+1. Enable the Google Sheets and Drive API
+1. Go to APIs & Services > Library and enable the Google Sheets API.
+1. Go to APIs & Services > Credentials and create a Service Account. This account will be used by your application to access the Google Sheets API.
+1. After creating the Service Account, click on it in the Credentials section, go to the Keys tab, and create a JSON key. This will download a JSON file with credentials for your Service Account.
+1. Open the JSON file and store its content securely. You’ll set this JSON content as an environment variable.
+1. Configure Access to the Google Sheet
+1. Open the Google Sheet you want to access.
+1. Click Share and add the Service Account email (found in the JSON file under "client_email") as a collaborator, typically with Editor access. This allows the Service Account to interact with the sheet.
+
+### Test that the credentials work with a direct call to the Integration
+
+```shell
+make test-googlesheet
+```
+
+## Add Secrets or Environment Variables
+
+1. Define the new secret or environment variable in the `api/settings.py` file.
+1. Add the new secret or environment variable to your local `.env` file.
+1. Test locally.
+1. Log into the AWS console and navigate to the Secrets Manager.
+1. Environment variables are added into the json secret named ENV_VARIABLES_SECRET_NAME in deploy.py for a given environment.
+1. Environment variables MUST be named the same as the property in the Settings class.
+1. Secret names MUST be the same as the property in the Settings class but with \_ replaced with - and prefixed with the environment name-.
+1. The deploy script will load the environment variables from the secret and set them in the container definition.
+1. The deploy script will map the secrets from Settings and match them to the container secrets.
+1. If any secrets are missing, the deploy script with retrieve the secret ARN and set the secret in the container definition.
+
+## AWS Deployment
+
+Locally test the deployment script like so:
+
+```shell
+AWS_PROFILE=robotics_ai_staging make dry-deploy ENV=staging
+```
+
+Locally deploy to the staging environment like so:
+
+```shell
+AWS_PROFILE=robotics_ai_staging make deploy ENV=staging
+```
diff --git a/opentrons-ai-server/api/handler/fast.py b/opentrons-ai-server/api/handler/fast.py
index 9534906adbe..9182f827a9a 100644
--- a/opentrons-ai-server/api/handler/fast.py
+++ b/opentrons-ai-server/api/handler/fast.py
@@ -1,14 +1,14 @@
import asyncio
import os
import time
-from typing import Any, Awaitable, Callable, List, Literal, Union
+from typing import Annotated, Any, Awaitable, Callable, List, Literal, Union
import structlog
from asgi_correlation_id import CorrelationIdMiddleware
from asgi_correlation_id.context import correlation_id
from ddtrace import tracer
from ddtrace.contrib.asgi.middleware import TraceMiddleware
-from fastapi import FastAPI, HTTPException, Query, Request, Response, Security, status
+from fastapi import BackgroundTasks, FastAPI, HTTPException, Query, Request, Response, Security, status
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
@@ -21,13 +21,17 @@
from api.domain.openai_predict import OpenAIPredict
from api.handler.custom_logging import setup_logging
from api.integration.auth import VerifyToken
+from api.integration.google_sheets import GoogleSheetsClient
from api.models.chat_request import ChatRequest
from api.models.chat_response import ChatResponse
from api.models.create_protocol import CreateProtocol
from api.models.empty_request_error import EmptyRequestError
+from api.models.error_response import ErrorResponse
+from api.models.feedback_request import FeedbackRequest
from api.models.feedback_response import FeedbackResponse
from api.models.internal_server_error import InternalServerError
from api.models.update_protocol import UpdateProtocol
+from api.models.user import User
from api.settings import Settings
settings: Settings = Settings()
@@ -38,6 +42,7 @@
auth: VerifyToken = VerifyToken()
openai: OpenAIPredict = OpenAIPredict(settings)
+google_sheets_client = GoogleSheetsClient(settings)
# Initialize FastAPI app with metadata
@@ -147,10 +152,6 @@ class Status(BaseModel):
version: str
-class ErrorResponse(BaseModel):
- message: str
-
-
class HealthResponse(BaseModel):
status: Status
@@ -175,7 +176,7 @@ class CorsHeadersResponse(BaseModel):
description="Generate a chat response based on the provided prompt.",
)
async def create_chat_completion(
- body: ChatRequest, auth_result: Any = Security(auth.verify) # noqa: B008
+ body: ChatRequest, user: Annotated[User, Security(auth.verify)]
) -> Union[ChatResponse, ErrorResponse]: # noqa: B008
"""
Generate a chat completion response using OpenAI.
@@ -183,7 +184,7 @@ async def create_chat_completion(
- **request**: The HTTP request containing the chat message.
- **returns**: A chat response or an error message.
"""
- logger.info("POST /api/chat/completion", extra={"body": body.model_dump(), "auth_result": auth_result})
+ logger.info("POST /api/chat/completion", extra={"body": body.model_dump(), "user": user})
try:
if not body.message or body.message == "":
raise HTTPException(
@@ -198,9 +199,9 @@ async def create_chat_completion(
response: Union[str, None] = openai.predict(prompt=body.message, chat_completion_message_params=body.history)
if response is None or response == "":
- return ChatResponse(reply="No response was generated", fake=body.fake)
+ return ChatResponse(reply="No response was generated", fake=bool(body.fake))
- return ChatResponse(reply=response, fake=body.fake)
+ return ChatResponse(reply=response, fake=bool(body.fake))
except Exception as e:
logger.exception("Error processing chat completion")
@@ -217,15 +218,15 @@ async def create_chat_completion(
description="Generate a chat response based on the provided prompt that will update an existing protocol with the required changes.",
)
async def update_protocol(
- body: UpdateProtocol, auth_result: Any = Security(auth.verify) # noqa: B008
+ body: UpdateProtocol, user: Annotated[User, Security(auth.verify)]
) -> Union[ChatResponse, ErrorResponse]: # noqa: B008
"""
- Generate an updated protocolusing OpenAI.
+ Generate an updated protocol using OpenAI.
- **request**: The HTTP request containing the existing protocol and other relevant parameters.
- **returns**: A chat response or an error message.
"""
- logger.info("POST /api/chat/updateProtocol", extra={"body": body.model_dump(), "auth_result": auth_result})
+ logger.info("POST /api/chat/updateProtocol", extra={"body": body.model_dump(), "user": user})
try:
if not body.protocol_text or body.protocol_text == "":
raise HTTPException(
@@ -233,14 +234,14 @@ async def update_protocol(
)
if body.fake:
- return ChatResponse(reply="Fake response", fake=body.fake)
+ return ChatResponse(reply="Fake response", fake=bool(body.fake))
response: Union[str, None] = openai.predict(prompt=body.prompt, chat_completion_message_params=None)
if response is None or response == "":
- return ChatResponse(reply="No response was generated", fake=body.fake)
+ return ChatResponse(reply="No response was generated", fake=bool(body.fake))
- return ChatResponse(reply=response, fake=body.fake)
+ return ChatResponse(reply=response, fake=bool(body.fake))
except Exception as e:
logger.exception("Error processing protocol update")
@@ -257,15 +258,15 @@ async def update_protocol(
description="Generate a chat response based on the provided prompt that will create a new protocol with the required changes.",
)
async def create_protocol(
- body: CreateProtocol, auth_result: Any = Security(auth.verify) # noqa: B008
+ body: CreateProtocol, user: Annotated[User, Security(auth.verify)]
) -> Union[ChatResponse, ErrorResponse]: # noqa: B008
"""
- Generate an updated protocolusing OpenAI.
+ Generate an updated protocol using OpenAI.
- **request**: The HTTP request containing the chat message.
- **returns**: A chat response or an error message.
"""
- logger.info("POST /api/chat/createProtocol", extra={"body": body.model_dump(), "auth_result": auth_result})
+ logger.info("POST /api/chat/createProtocol", extra={"body": body.model_dump(), "user": user})
try:
if not body.prompt or body.prompt == "":
@@ -279,9 +280,9 @@ async def create_protocol(
response: Union[str, None] = openai.predict(prompt=str(body.model_dump()), chat_completion_message_params=None)
if response is None or response == "":
- return ChatResponse(reply="No response was generated", fake=body.fake)
+ return ChatResponse(reply="No response was generated", fake=bool(body.fake))
- return ChatResponse(reply=response, fake=body.fake)
+ return ChatResponse(reply=response, fake=bool(body.fake))
except Exception as e:
logger.exception("Error processing protocol creation")
@@ -339,23 +340,19 @@ async def redoc_html() -> HTMLResponse:
summary="Feedback",
description="Send feedback to the team.",
)
-async def feedback(request: Request, auth_result: Any = Security(auth.verify)) -> FeedbackResponse: # noqa: B008
- """
- Send feedback to the team.
-
- - **request**: The HTTP request containing the feedback message.
- - **returns**: A feedback response or an error message.
- """
+async def feedback(
+ body: FeedbackRequest, user: Annotated[User, Security(auth.verify)], background_tasks: BackgroundTasks
+) -> FeedbackResponse:
logger.info("POST /api/feedback")
try:
- body = await request.json()
- if "feedbackText" not in body.keys() or body["feedbackText"] == "":
- logger.info("Feedback empty")
- raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=EmptyRequestError(message="Request body is empty"))
- logger.info(f"Feedback received: {body}")
- feedbackText = body["feedbackText"]
- # todo: Store feedback text in a database
- return FeedbackResponse(reply=f"Feedback Received: {feedbackText}", fake=False)
+ if body.fake:
+ return FeedbackResponse(reply="Fake response", fake=bool(body.fake))
+ feedback_text = body.feedbackText
+ logger.info("Feedback received", user_id=user.sub, feedback=feedback_text)
+ background_tasks.add_task(google_sheets_client.append_feedback_to_sheet, user_id=str(user.sub), feedback=feedback_text)
+ return FeedbackResponse(
+ reply=f"Feedback Received and sanitized: {google_sheets_client.sanitize_for_google_sheets(feedback_text)}", fake=False
+ )
except Exception as e:
logger.exception("Error processing feedback")
diff --git a/opentrons-ai-server/api/integration/auth.py b/opentrons-ai-server/api/integration/auth.py
index 12e8b2a4a9e..addc0abafb8 100644
--- a/opentrons-ai-server/api/integration/auth.py
+++ b/opentrons-ai-server/api/integration/auth.py
@@ -1,10 +1,9 @@
-from typing import Any, Optional
-
import jwt
import structlog
from fastapi import HTTPException, Security, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer, SecurityScopes
+from api.models.user import User
from api.settings import Settings
settings: Settings = Settings()
@@ -28,8 +27,8 @@ def __init__(self) -> None:
self.jwks_client = jwt.PyJWKClient(jwks_url)
async def verify(
- self, security_scopes: SecurityScopes, credentials: Optional[HTTPAuthorizationCredentials] = Security(HTTPBearer()) # noqa: B008
- ) -> Any:
+ self, security_scopes: SecurityScopes, credentials: HTTPAuthorizationCredentials = Security(HTTPBearer()) # noqa: B008
+ ) -> User:
if credentials is None:
raise UnauthenticatedException()
@@ -50,8 +49,9 @@ async def verify(
audience=self.config.auth0_api_audience,
issuer=self.config.auth0_issuer,
)
- logger.info("Decoded token", extra={"token": payload})
- return payload
+ user = User(**payload)
+ logger.info("User object", extra={"user": user})
+ return user
except jwt.ExpiredSignatureError:
logger.error("Expired Signature", extra={"credentials": credentials}, exc_info=True)
# Handle token expiration, e.g., refresh token, re-authenticate, etc.
diff --git a/opentrons-ai-server/api/integration/google_sheets.py b/opentrons-ai-server/api/integration/google_sheets.py
new file mode 100644
index 00000000000..e86d4103097
--- /dev/null
+++ b/opentrons-ai-server/api/integration/google_sheets.py
@@ -0,0 +1,75 @@
+import json
+import random
+import re
+
+import gspread
+import structlog
+from google.oauth2.service_account import Credentials
+from gspread import SpreadsheetNotFound # type: ignore
+from gspread.client import Client as GspreadClient
+
+from api.settings import Settings
+
+
+class GoogleSheetsClient:
+ SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]
+
+ def __init__(self, settings: Settings) -> None:
+ self.settings = settings
+ self.logger = structlog.stdlib.get_logger(settings.logger_name)
+ self.client: GspreadClient = self._initialize_client()
+
+ def _initialize_client(self) -> GspreadClient:
+ """Initialize the gspread client with Service Account credentials loaded from the environment."""
+ creds: Credentials = self._get_credentials()
+ return gspread.authorize(creds) # type: ignore
+
+ def _get_credentials(self) -> Credentials:
+ """Load Service Account credentials from an environment variable."""
+ google_credentials_json = self.settings.google_credentials_json.get_secret_value()
+ if not google_credentials_json:
+ raise EnvironmentError("Missing GOOGLE_SHEETS_CREDENTIALS environment variable.")
+
+ creds_info = json.loads(google_credentials_json)
+ creds: Credentials = Credentials.from_service_account_info(info=creds_info, scopes=self.SCOPES) # type: ignore
+ return creds
+
+ @staticmethod
+ def sanitize_for_google_sheets(input_text: str) -> str:
+ """Sanitize input to remove JavaScript and HTML tags, and prevent formulas."""
+ script_pattern = re.compile(r'(javascript:[^"]*|.*?|on\w+=".*?"|on\w+=\'.*?\')', re.IGNORECASE)
+ sanitized_text = re.sub(script_pattern, "", input_text)
+ sanitized_text = re.sub(r"(<.*?>|<.*?>)", "", sanitized_text)
+ sanitized_text = re.sub(r"^\s*=\s*", "", sanitized_text)
+ return sanitized_text.strip()
+
+ def append_feedback_to_sheet(self, user_id: str, feedback: str) -> None:
+ """Append a row of feedback to the Google Sheet."""
+ try:
+ sheet_id = self.settings.google_sheet_id
+ worksheet_name = self.settings.google_sheet_worksheet
+ spreadsheet = self.client.open_by_key(sheet_id)
+ worksheet = spreadsheet.worksheet(worksheet_name)
+
+ feedback = self.sanitize_for_google_sheets(feedback)
+
+ worksheet.append_row([user_id, feedback])
+ self.logger.info("Feedback successfully appended to Google Sheet.")
+ except SpreadsheetNotFound:
+ self.logger.error("Spreadsheet not found or not accessible.")
+ except Exception:
+ self.logger.error("Error appending feedback to Google Sheet.", exc_info=True)
+
+
+# Example usage
+def main() -> None:
+ """Run an example appending feedback to Google Sheets."""
+ settings = Settings()
+ google_sheets_client = GoogleSheetsClient(settings)
+ user_id = str(random.randint(100000, 999999))
+ feedback = f"This is a test feedback for user {user_id}."
+ google_sheets_client.append_feedback_to_sheet(user_id, feedback)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/opentrons-ai-server/api/models/create_protocol.py b/opentrons-ai-server/api/models/create_protocol.py
index 5b011284848..f94d87d2bf8 100644
--- a/opentrons-ai-server/api/models/create_protocol.py
+++ b/opentrons-ai-server/api/models/create_protocol.py
@@ -5,6 +5,7 @@
class CreateProtocol(BaseModel):
prompt: str = Field(..., description="Prompt")
+ regenerate: bool = Field(..., description="Flag to indicate if regeneration is needed")
scientific_application_type: str = Field(..., description="Scientific application type")
description: str = Field(..., description="Description of the protocol")
robots: Literal["opentrons_flex", "opentrons_ot2"] = Field(..., description="List of required robots")
diff --git a/opentrons-ai-server/api/models/error_response.py b/opentrons-ai-server/api/models/error_response.py
new file mode 100644
index 00000000000..ba52d60547e
--- /dev/null
+++ b/opentrons-ai-server/api/models/error_response.py
@@ -0,0 +1,5 @@
+from pydantic import BaseModel
+
+
+class ErrorResponse(BaseModel):
+ message: str
diff --git a/opentrons-ai-server/api/models/feedback_request.py b/opentrons-ai-server/api/models/feedback_request.py
new file mode 100644
index 00000000000..89a098b0f92
--- /dev/null
+++ b/opentrons-ai-server/api/models/feedback_request.py
@@ -0,0 +1,15 @@
+from typing import Optional
+
+from pydantic import BaseModel, Field, field_validator
+
+
+class FeedbackRequest(BaseModel):
+ feedbackText: str = Field(..., description="The feedback message content")
+ fake: Optional[bool] = Field(False, description="Indicates if this is a fake feedback entry")
+
+ # Validation to ensure feedback_text is populated and not empty
+ @field_validator("feedbackText")
+ def feedback_text_must_not_be_empty(cls, value: str) -> str:
+ if not value or value.strip() == "":
+ raise ValueError("feedback_text must be populated and not empty")
+ return value
diff --git a/opentrons-ai-server/api/models/user.py b/opentrons-ai-server/api/models/user.py
new file mode 100644
index 00000000000..d1d79c2b6d1
--- /dev/null
+++ b/opentrons-ai-server/api/models/user.py
@@ -0,0 +1,16 @@
+from typing import List, Optional, Union
+
+from pydantic import BaseModel, Field
+
+
+class User(BaseModel):
+ aud: Union[str, List[str]] = Field(..., description="Audience URL(s)")
+ azp: str = Field(..., description="Authorized party ID")
+ exp: int = Field(..., description="Expiration timestamp")
+ iat: int = Field(..., description="Issued-at timestamp")
+ iss: str = Field(..., description="Issuer URL")
+ scope: Optional[str] = Field(None, description="Space-separated scopes")
+ sub: str = Field(..., description="Subject identifier for the token")
+
+ class Config:
+ extra = "allow" # Allows additional fields not specified in the model
diff --git a/opentrons-ai-server/api/settings.py b/opentrons-ai-server/api/settings.py
index c59a25c33de..9557b51614b 100644
--- a/opentrons-ai-server/api/settings.py
+++ b/opentrons-ai-server/api/settings.py
@@ -34,11 +34,15 @@ class Settings(BaseSettings):
dd_trace_enabled: str = "false"
cpu: str = "1028"
memory: str = "2048"
+ google_sheet_id: str = "harcoded_default_from_settings"
+ google_sheet_worksheet: str = "Sheet1"
# Secrets
# These come from environment variables in the local and deployed execution environments
openai_api_key: SecretStr = SecretStr("default_openai_api_key")
huggingface_api_key: SecretStr = SecretStr("default_huggingface_api_key")
+ google_credentials_json: SecretStr = SecretStr("default_google_credentials_json")
+ datadog_api_key: SecretStr = SecretStr("default_datadog_api_key")
@property
def json_logging(self) -> bool:
diff --git a/opentrons-ai-server/deploy.py b/opentrons-ai-server/deploy.py
index 61cbc64b9a1..813dc3ccca1 100644
--- a/opentrons-ai-server/deploy.py
+++ b/opentrons-ai-server/deploy.py
@@ -3,7 +3,7 @@
import datetime
import subprocess
from dataclasses import dataclass
-from typing import Dict, List
+from typing import Any, Dict, List
import boto3
import docker
@@ -12,7 +12,7 @@
from rich import print
from rich.prompt import Prompt
-ENVIRONMENTS = ["crt", "dev", "sandbox", "staging", "prod"]
+ENVIRONMENTS = ["staging", "prod"]
def get_aws_account_id() -> str:
@@ -28,6 +28,7 @@ def get_aws_region() -> str:
@dataclass(frozen=True)
class BaseDeploymentConfig:
+ ENV: str
IMAGE_NAME: str # local image name
ECR_URL: str
ECR_REPOSITORY: str
@@ -40,42 +41,9 @@ class BaseDeploymentConfig:
DEPLOYMENT_POLL_INTERVAL_S: int = 20
-@dataclass(frozen=True)
-class CrtDeploymentConfig(BaseDeploymentConfig):
- ECR_REPOSITORY: str = "crt-ecr-repo"
- ECR_URL: str = f"{get_aws_account_id()}.dkr.ecr.{get_aws_region()}.amazonaws.com"
- IMAGE_NAME: str = "crt-ai-server"
- CLUSTER_NAME: str = "crt-ai-cluster"
- SERVICE_NAME: str = "crt-ai-service"
- CONTAINER_NAME: str = "crt-ai-api"
- ENV_VARIABLES_SECRET_NAME: str = "crt-environment-variables"
-
-
-@dataclass(frozen=True)
-class SandboxDeploymentConfig(BaseDeploymentConfig):
- ECR_REPOSITORY: str = "sandbox-ecr-repo"
- ECR_URL: str = f"{get_aws_account_id()}.dkr.ecr.{get_aws_region()}.amazonaws.com"
- IMAGE_NAME: str = "sandbox-ai-server"
- CLUSTER_NAME: str = "sandbox-ai-cluster"
- SERVICE_NAME: str = "sandbox-ai-service"
- CONTAINER_NAME: str = "sandbox-ai-api"
- ENV_VARIABLES_SECRET_NAME: str = "sandbox-environment-variables"
-
-
-@dataclass(frozen=True)
-class DevDeploymentConfig(BaseDeploymentConfig):
- ECR_REPOSITORY: str = "dev-ecr-repo"
- ECR_URL: str = f"{get_aws_account_id()}.dkr.ecr.{get_aws_region()}.amazonaws.com"
- FUNCTION_NAME: str = "dev-api-function"
- IMAGE_NAME: str = "dev-ai-server"
- CLUSTER_NAME: str = "dev-ai-cluster"
- SERVICE_NAME: str = "dev-ai-service"
- CONTAINER_NAME: str = "dev-ai-api"
- ENV_VARIABLES_SECRET_NAME: str = "dev-environment-variables"
-
-
@dataclass(frozen=True)
class StagingDeploymentConfig(BaseDeploymentConfig):
+ ENV: str = "staging"
ECR_REPOSITORY: str = "staging-ecr-repo"
ECR_URL: str = f"{get_aws_account_id()}.dkr.ecr.{get_aws_region()}.amazonaws.com"
IMAGE_NAME: str = "staging-ai-server"
@@ -87,6 +55,7 @@ class StagingDeploymentConfig(BaseDeploymentConfig):
@dataclass(frozen=True)
class ProdDeploymentConfig(BaseDeploymentConfig):
+ ENV: str = "prod"
ECR_REPOSITORY: str = "prod-ecr-repo"
ECR_URL: str = f"{get_aws_account_id()}.dkr.ecr.{get_aws_region()}.amazonaws.com"
IMAGE_NAME: str = "prod-ai-server"
@@ -156,7 +125,43 @@ def update_environment_variables(self, environment_variables: List[Dict[str, str
return updated_environment_variables
- def update_ecs_task(self) -> None:
+ def get_secret_arn(self, secret_name: str) -> str:
+ response = self.secret_manager_client.describe_secret(SecretId=secret_name)
+ return str(response["ARN"])
+
+ def update_secrets_in_container_definition(self, container_definition: dict[str, Any]) -> None:
+ expected_secrets = {field.upper() for field, field_type in self.env_variables.__annotations__.items() if field_type == SecretStr}
+ print(f"Expected secrets: {expected_secrets}")
+
+ task_secrets = {secret["name"].upper() for secret in container_definition.get("secrets", [])}
+ print(f"Existing secrets: {task_secrets}")
+
+ if not task_secrets:
+ raise ValueError("No secrets found in the api container definition ...")
+
+ unexpected_secrets = [secret.upper() for secret in task_secrets if secret not in expected_secrets]
+ if unexpected_secrets:
+ raise ValueError(f"Secrets found in the api container definition that are NOT in Settings: {', '.join(unexpected_secrets)}")
+
+ missing_secrets = [secret.upper() for secret in expected_secrets if secret.upper() not in task_secrets]
+
+ if missing_secrets:
+ print(f"Missing secrets: {missing_secrets}")
+ for secret in missing_secrets:
+ print(f"Adding missing secret: {secret}")
+ # secret name is the same as the property name
+ # of the secret in the Settings class
+ # but with _ replaced with -
+ secret_name = f"{self.config.ENV}-{secret.lower().replace("_", "-")}"
+ value_from = self.get_secret_arn(secret_name)
+ # name is the all caps version of the secret name
+ # valueFrom is the ARN of the secret
+ new_secret = {"name": secret, "valueFrom": value_from}
+ container_definition["secrets"].append(new_secret)
+ else:
+ print("No secrets need to be added.")
+
+ def update_ecs_task(self, dry: bool) -> None:
print(f"Updating ECS task with new image: {self.full_image_name}")
response = self.ecs_client.describe_services(cluster=self.config.CLUSTER_NAME, services=[self.config.SERVICE_NAME])
task_definition_arn = response["services"][0]["taskDefinition"]
@@ -164,6 +169,9 @@ def update_ecs_task(self) -> None:
task_definition = self.ecs_client.describe_task_definition(taskDefinition=task_definition_arn)["taskDefinition"]
container_definitions = task_definition["containerDefinitions"]
for container_definition in container_definitions:
+ # ENV--datadog-agent container has one secret and 2 environment variables
+ # ENV--log-router container has no secrets or environment variables
+ # These are managed in the infra repo, NOT here
if container_definition["name"] == self.config.CONTAINER_NAME:
container_definition["image"] = self.full_image_name
environment_variables = container_definition.get("environment", [])
@@ -171,13 +179,15 @@ def update_ecs_task(self) -> None:
for key, value in self.env_variables.model_dump().items():
if not isinstance(value, SecretStr):
# Secrets are not set here
- # They are set in the secrets key of ECS task definition
+ # They are set in the secrets key of the containerDefinition
environment_variables = self.update_environment_variables(environment_variables, key, value)
# Overwrite the DD_VERSION environment variable
# with the current deployment tag
# this is what we are using for version currently
environment_variables = self.update_environment_variables(environment_variables, "DD_VERSION", self.config.TAG)
container_definition["environment"] = environment_variables
+ # Update the secrets in the container definition
+ self.update_secrets_in_container_definition(container_definition)
print("Updated container definition:")
print(container_definition)
break
@@ -195,6 +205,11 @@ def update_ecs_task(self) -> None:
}
print("New task definition:")
print(new_task_definition)
+
+ if dry:
+ print("Dry run, not updating the ECS task.")
+ return
+
register_response = self.ecs_client.register_task_definition(**new_task_definition)
new_task_definition_arn = register_response["taskDefinition"]["taskDefinitionArn"]
@@ -204,14 +219,21 @@ def update_ecs_task(self) -> None:
taskDefinition=new_task_definition_arn,
forceNewDeployment=True,
)
+ print(f"Deployment to {self.config.ENV} started.")
+ print("The API container definition was updated.")
+ print("A new Task definition was defined and registered.")
+ print("Then we told the ECS service to deploy the new definition.")
+ print("Monitor the deployment in the ECS console.")
def main() -> None:
parser = argparse.ArgumentParser(description="Manage ECS Fargate deployment.")
parser.add_argument("--env", type=str, help=f"Deployment environment {ENVIRONMENTS}")
parser.add_argument("--tag", type=str, help="The tag and therefore version of the container to use")
+ # action="store_true" sets args.dry to True only if --dry is provided on the command line
+ parser.add_argument("--dry", action="store_true", help="Dry run, do not make any changes")
args = parser.parse_args()
- # Determine if the script was called with command-line arguments
+
if args.env:
if args.env.lower() not in ENVIRONMENTS:
print(f"[red]Invalid environment specified: {args.env}[/red]")
@@ -221,7 +243,6 @@ def main() -> None:
tag = args.tag
else:
if args.env:
- # Passing --env alone generates a tag and does not prompt!
tag = str(int(datetime.datetime.now().timestamp()))
else:
# Interactive prompts if env not set
@@ -237,24 +258,17 @@ def main() -> None:
config = ProdDeploymentConfig(TAG=tag)
elif env == "staging":
config = StagingDeploymentConfig(TAG=tag)
- elif env == "crt":
- config = CrtDeploymentConfig(TAG=tag)
- elif env == "dev":
- config = DevDeploymentConfig(TAG=tag)
- elif env == "sandbox":
- config = SandboxDeploymentConfig(TAG=tag)
else:
print(f"[red]Invalid environment specified: {env}[/red]")
exit(1)
aws = Deploy(config)
aws.build_docker_image()
- aws.push_docker_image_to_ecr()
- aws.update_ecs_task()
- print(f"Deployment to {env} started.")
- print(f"A new image was built and pushed to ECR with tag: {tag}")
- print("A new Task definition was defined and registered.")
- print("Then we told the ECS service to deploy the new definition.")
- print("Monitor the deployment in the ECS console.")
+ if args.dry:
+ print("Dry run, not pushing image to ECR.")
+ else:
+ aws.push_docker_image_to_ecr()
+ print(f"A new image was built and pushed to ECR with tag: {tag}")
+ aws.update_ecs_task(dry=args.dry)
if __name__ == "__main__":
diff --git a/opentrons-ai-server/tests/helpers/client.py b/opentrons-ai-server/tests/helpers/client.py
index 7c0d2383ffd..bf5a7febb3c 100644
--- a/opentrons-ai-server/tests/helpers/client.py
+++ b/opentrons-ai-server/tests/helpers/client.py
@@ -3,6 +3,7 @@
from typing import Any, Callable, Optional, TypeVar
from api.models.chat_request import ChatRequest, FakeKeys
+from api.models.feedback_request import FeedbackRequest
from httpx import Client as HttpxClient
from httpx import Response, Timeout
from rich.console import Console, Group
@@ -68,10 +69,13 @@ def get_chat_completion(self, message: str, fake: bool = True, fake_key: Optiona
headers = self.standard_headers if not bad_auth else self.invalid_auth_headers
return self.httpx.post("/chat/completion", headers=headers, json=request.model_dump())
- def get_feedback(self, message: str, fake: bool = True) -> Response:
+ def post_feedback(self, message: str, fake: bool = True, bad_auth: bool = False) -> Response:
"""Call the /chat/feedback endpoint and return the response."""
- request = f'{"feedbackText": "{message}"}'
- return self.httpx.post("/chat/feedback", headers=self.standard_headers, json=request)
+ request: dict[str, Any] = {"message": message, "fake": fake}
+ if message != "":
+ request = FeedbackRequest(feedbackText=message, fake=fake).model_dump()
+ headers = self.standard_headers if not bad_auth else self.invalid_auth_headers
+ return self.httpx.post("/chat/feedback", headers=headers, json=request)
def get_bad_endpoint(self, bad_auth: bool = False) -> Response:
"""Call nonexistent endpoint and return the response."""
@@ -113,6 +117,11 @@ def main() -> None:
response = client.get_health()
print_response(response)
+ console.print(Rule("Submit feedback", style="bold"))
+ feedback_message = Prompt.ask("Enter feedback message")
+ response = client.post_feedback(feedback_message, fake=False)
+ print_response(response)
+
console.print(Rule("Getting chat completion with fake=True and good auth (won't call OpenAI)", style="bold"))
response = client.get_chat_completion("How do I load a pipette?")
print_response(response)
diff --git a/opentrons-ai-server/tests/test_google_sheets_sanatize.py b/opentrons-ai-server/tests/test_google_sheets_sanatize.py
new file mode 100644
index 00000000000..b7b8e3778f0
--- /dev/null
+++ b/opentrons-ai-server/tests/test_google_sheets_sanatize.py
@@ -0,0 +1,23 @@
+import pytest
+from api.integration.google_sheets import GoogleSheetsClient
+
+
+@pytest.mark.unit
+@pytest.mark.parametrize(
+ "input_text, expected_output",
+ [
+ ('Click here!', "Click here!"),
+ ('javascript:alert("Malicious code")', '"Malicious code")'),
+ ("Important message", "Important message"),
+ ("onload=\"alert('Attack')\" Hello!", "Hello!"),
+ ('=IMPORTRANGE("https://example.com/sheet", "Sheet1!A1")', 'IMPORTRANGE("https://example.com/sheet", "Sheet1!A1")'),
+ ("Hello, world!", "Hello, world!"),
+ ("link", "link"),
+ ("=SUM(A1:A10)", "SUM(A1:A10)"),
+ ('', ""),
+ ('<script>alert("test")</script>', 'alert("test")'),
+ ],
+)
+def test_sanitize_for_google_sheets(input_text: str, expected_output: str) -> None:
+ sanitized_text = GoogleSheetsClient.sanitize_for_google_sheets(input_text)
+ assert sanitized_text == expected_output, f"Expected '{expected_output}' but got '{sanitized_text}'"
diff --git a/opentrons-ai-server/tests/test_live.py b/opentrons-ai-server/tests/test_live.py
index ce22f4ff405..797d21fe7b6 100644
--- a/opentrons-ai-server/tests/test_live.py
+++ b/opentrons-ai-server/tests/test_live.py
@@ -1,5 +1,6 @@
import pytest
from api.models.chat_response import ChatResponse
+from api.models.error_response import ErrorResponse
from api.models.feedback_response import FeedbackResponse
from tests.helpers.client import Client
@@ -28,13 +29,39 @@ def test_get_chat_completion_bad_auth(client: Client) -> None:
@pytest.mark.live
-def test_get_feedback_good_auth(client: Client) -> None:
+def test_post_feedback_good_auth(client: Client) -> None:
"""Test the feedback endpoint with good authentication."""
- response = client.get_feedback("How do I load tipracks for my 8 channel pipette on an OT2?", fake=True)
+ response = client.post_feedback("Would be nice if it were faster", fake=False)
assert response.status_code == 200, "Feedback with good auth should return HTTP 200"
+ assert response.json()["reply"] == "Feedback Received and sanitized: Would be nice if it were faster", "Response should contain input"
FeedbackResponse.model_validate(response.json())
+@pytest.mark.live
+def test_post_empty_feedback_good_auth(client: Client) -> None:
+ """Test the feedback endpoint with good authentication."""
+ response = client.post_feedback("", fake=False)
+ assert response.status_code == 422, "Feedback with feebackText = '' should return HTTP 422"
+ ErrorResponse.model_validate(response.json())
+
+
+@pytest.mark.live
+def test_post_feedback_good_auth_fake(client: Client) -> None:
+ """Test the feedback endpoint with good authentication."""
+ response = client.post_feedback("More LLM", fake=True)
+ assert response.status_code == 200, "Fake response"
+ assert response.json()["fake"] is True, "Fake indicator should be True"
+ assert response.json()["reply"] == "Fake response", "Response should be 'Fake response'"
+ FeedbackResponse.model_validate(response.json())
+
+
+@pytest.mark.live
+def test_post_feedback_bad_auth(client: Client) -> None:
+ """Test the feedback endpoint with bad authentication."""
+ response = client.post_feedback("How do I load tipracks for my 8 channel pipette on an OT2?", fake=False, bad_auth=True)
+ assert response.status_code == 401, "Feedback with bad auth should return HTTP 401"
+
+
@pytest.mark.live
def test_get_bad_endpoint_with_good_auth(client: Client) -> None:
"""Test a nonexistent endpoint with good authentication."""
diff --git a/protocol-designer/src/organisms/AssignLiquidsModal/LiquidToolbox.tsx b/protocol-designer/src/organisms/AssignLiquidsModal/LiquidToolbox.tsx
index 9e9442cf726..7bca54d3f67 100644
--- a/protocol-designer/src/organisms/AssignLiquidsModal/LiquidToolbox.tsx
+++ b/protocol-designer/src/organisms/AssignLiquidsModal/LiquidToolbox.tsx
@@ -53,7 +53,7 @@ interface LiquidToolboxProps {
}
export function LiquidToolbox(props: LiquidToolboxProps): JSX.Element {
const { onClose } = props
- const { t } = useTranslation(['liquids', 'shared', 'form'])
+ const { t } = useTranslation(['liquids', 'form', 'shared'])
const dispatch = useDispatch()
const [showDefineLiquidModal, setDefineLiquidModal] = useState(false)
const liquids = useSelector(labwareIngredSelectors.allIngredientNamesIds)
diff --git a/protocol-designer/src/organisms/WellOrderModal/index.tsx b/protocol-designer/src/organisms/WellOrderModal/index.tsx
index 91a7406104e..cb0d7d64ee4 100644
--- a/protocol-designer/src/organisms/WellOrderModal/index.tsx
+++ b/protocol-designer/src/organisms/WellOrderModal/index.tsx
@@ -92,8 +92,7 @@ export function WellOrderModal(props: WellOrderModalProps): JSX.Element | null {
}
const handleReset = (): void => {
- setWellOrder({ firstValue: DEFAULT_FIRST, secondValue: DEFAULT_SECOND })
- applyChanges()
+ updateValues(DEFAULT_FIRST, DEFAULT_SECOND)
closeModal()
}
@@ -144,6 +143,13 @@ export function WellOrderModal(props: WellOrderModalProps): JSX.Element | null {
if (!isOpen) return null
+ let secondaryOptions = WELL_ORDER_VALUES
+ if (VERTICAL_VALUES.includes(wellOrder.firstValue)) {
+ secondaryOptions = HORIZONTAL_VALUES
+ } else if (HORIZONTAL_VALUES.includes(wellOrder.firstValue)) {
+ secondaryOptions = VERTICAL_VALUES
+ }
+
return createPortal(
({
+ filterOptions={secondaryOptions.map(value => ({
value,
name: t(`step_edit_form.field.well_order.option.${value}`),
disabled: isSecondOptionDisabled(value),
diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/SelectPipettes.tsx b/protocol-designer/src/pages/CreateNewProtocolWizard/SelectPipettes.tsx
index 33aa24787fb..fc811b2665a 100644
--- a/protocol-designer/src/pages/CreateNewProtocolWizard/SelectPipettes.tsx
+++ b/protocol-designer/src/pages/CreateNewProtocolWizard/SelectPipettes.tsx
@@ -182,7 +182,6 @@ export function SelectPipettes(props: WizardTileProps): JSX.Element | null {
{page === 'add' ? (
diff --git a/protocol-designer/src/pages/CreateNewProtocolWizard/WizardBody.tsx b/protocol-designer/src/pages/CreateNewProtocolWizard/WizardBody.tsx
index 140878c9994..b5d69253435 100644
--- a/protocol-designer/src/pages/CreateNewProtocolWizard/WizardBody.tsx
+++ b/protocol-designer/src/pages/CreateNewProtocolWizard/WizardBody.tsx
@@ -2,8 +2,8 @@ import type * as React from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import {
- ALIGN_END,
ALIGN_CENTER,
+ ALIGN_END,
BORDERS,
Btn,
COLORS,
@@ -11,10 +11,11 @@ import {
Flex,
JUSTIFY_SPACE_BETWEEN,
LargeButton,
+ OVERFLOW_SCROLL,
SPACING,
StyledText,
- TYPOGRAPHY,
Tooltip,
+ TYPOGRAPHY,
useHoverTooltip,
} from '@opentrons/components'
import temporaryImg from '../../assets/images/placeholder_image_delete.png'
@@ -56,13 +57,19 @@ export function WizardBody(props: WizardBodyProps): JSX.Element {
>
-
+
- {labwareLoadedOnModule != null ? (
+ {labwareLoadedOnModule != null &&
+ !isLabwareOccludedByThermocyclerLid ? (
<>
option.value === selectedValue) ?? options[0]
+ }
onClick={value => {
updateValue(value)
setSelectedValue(value)
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ConnectedStepInfo.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ConnectedStepInfo.tsx
index 778159b6d31..c198359ab52 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ConnectedStepInfo.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/ConnectedStepInfo.tsx
@@ -1,4 +1,5 @@
import { useDispatch, useSelector } from 'react-redux'
+import type { Dispatch, SetStateAction } from 'react'
import { useTranslation } from 'react-i18next'
import { useConditionalConfirm } from '@opentrons/components'
import * as timelineWarningSelectors from '../../../../top-selectors/timelineWarnings'
@@ -33,7 +34,6 @@ import {
nonePressed,
} from './utils'
-import type * as React from 'react'
import type { ThunkDispatch } from 'redux-thunk'
import type {
HoverOnStepAction,
@@ -47,10 +47,18 @@ export interface ConnectedStepInfoProps {
stepId: StepIdType
stepNumber: number
dragHovered?: boolean
+ openedOverflowMenuId?: string | null
+ setOpenedOverflowMenuId?: Dispatch>
}
export function ConnectedStepInfo(props: ConnectedStepInfoProps): JSX.Element {
- const { stepId, stepNumber, dragHovered = false } = props
+ const {
+ stepId,
+ stepNumber,
+ dragHovered = false,
+ openedOverflowMenuId,
+ setOpenedOverflowMenuId,
+ } = props
const { t } = useTranslation('application')
const dispatch = useDispatch>()
const stepIds = useSelector(getOrderedStepIds)
@@ -203,6 +211,8 @@ export function ConnectedStepInfo(props: ConnectedStepInfoProps): JSX.Element {
/>
)}
void
findStepIndex: (stepId: StepIdType) => number
orderedStepIds: string[]
+ openedOverflowMenuId?: string | null
+ setOpenedOverflowMenuId?: Dispatch>
}
interface DropType {
@@ -30,7 +33,15 @@ interface DropType {
}
function DragDropStep(props: DragDropStepProps): JSX.Element {
- const { stepId, moveStep, findStepIndex, orderedStepIds, stepNumber } = props
+ const {
+ stepId,
+ moveStep,
+ findStepIndex,
+ orderedStepIds,
+ stepNumber,
+ openedOverflowMenuId,
+ setOpenedOverflowMenuId,
+ } = props
const stepRef = useRef(null)
const [{ isDragging }, drag] = useDrag(
@@ -73,6 +84,8 @@ function DragDropStep(props: DragDropStepProps): JSX.Element {
data-handler-id={handlerId}
>
(null)
const findStepIndex = (stepId: StepIdType): number =>
orderedStepIds.findIndex(id => stepId === id)
@@ -123,6 +139,8 @@ export function DraggableSteps(props: DraggableStepsProps): JSX.Element | null {
moveStep={moveStep}
findStepIndex={findStepIndex}
orderedStepIds={orderedStepIds}
+ openedOverflowMenuId={openedOverflowMenuId}
+ setOpenedOverflowMenuId={setOpenedOverflowMenuId}
/>
))}
diff --git a/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/StepContainer.tsx b/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/StepContainer.tsx
index ce5860b2cbf..4ed55987f08 100644
--- a/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/StepContainer.tsx
+++ b/protocol-designer/src/pages/Designer/ProtocolSteps/Timeline/StepContainer.tsx
@@ -35,6 +35,11 @@ import { LINE_CLAMP_TEXT_STYLE } from '../../../../atoms'
import { StepOverflowMenu } from './StepOverflowMenu'
import { capitalizeFirstLetterAfterNumber } from './utils'
+import type {
+ SetStateAction,
+ Dispatch,
+ MouseEvent as ReactMouseEvent,
+} from 'react'
import type { ThunkDispatch } from 'redux-thunk'
import type { IconName } from '@opentrons/components'
import type { StepIdType } from '../../../../form-types'
@@ -42,16 +47,18 @@ import type { BaseState } from '../../../../types'
const STARTING_DECK_STATE = 'Starting deck state'
const FINAL_DECK_STATE = 'Final deck state'
-
+const PX_HEIGHT_TO_TOP_OF_CONTAINER = 32
export interface StepContainerProps {
title: string
iconName: IconName
+ openedOverflowMenuId?: string | null
+ setOpenedOverflowMenuId?: Dispatch>
stepId?: string
iconColor?: string
- onClick?: (event: React.MouseEvent) => void
- onDoubleClick?: (event: React.MouseEvent) => void
- onMouseEnter?: (event: React.MouseEvent) => void
- onMouseLeave?: (event: React.MouseEvent) => void
+ onClick?: (event: ReactMouseEvent) => void
+ onDoubleClick?: (event: ReactMouseEvent) => void
+ onMouseEnter?: (event: ReactMouseEvent) => void
+ onMouseLeave?: (event: ReactMouseEvent) => void
selected?: boolean
hovered?: boolean
hasError?: boolean
@@ -74,10 +81,11 @@ export function StepContainer(props: StepContainerProps): JSX.Element {
hasError = false,
isStepAfterError = false,
dragHovered = false,
+ setOpenedOverflowMenuId,
+ openedOverflowMenuId,
} = props
const [top, setTop] = useState(0)
const menuRootRef = useRef(null)
- const [stepOverflowMenu, setStepOverflowMenu] = useState(false)
const isStartingOrEndingState =
title === STARTING_DECK_STATE || title === FINAL_DECK_STATE
const dispatch = useDispatch>()
@@ -104,22 +112,21 @@ export function StepContainer(props: StepContainerProps): JSX.Element {
menuRootRef.current?.contains(event.target)
)
- if (wasOutside && stepOverflowMenu) {
- setStepOverflowMenu(false)
+ if (wasOutside) {
+ setOpenedOverflowMenuId?.(null)
}
}
- const handleOverflowClick = (event: React.MouseEvent): void => {
- const { clientY } = event
-
+ const handleOverflowClick = (event: ReactMouseEvent): void => {
+ const buttonRect = event.currentTarget.getBoundingClientRect()
const screenHeight = window.innerHeight
- const rootHeight = menuRootRef.current
- ? menuRootRef.current.offsetHeight
- : 0
+ const rootHeight = menuRootRef.current?.offsetHeight || 0
+
+ const spaceBelow = screenHeight - buttonRect.bottom
const top =
- screenHeight - clientY > rootHeight
- ? clientY + 5
- : clientY - rootHeight - 5
+ spaceBelow > rootHeight
+ ? buttonRect.bottom - PX_HEIGHT_TO_TOP_OF_CONTAINER
+ : buttonRect.top - rootHeight + PX_HEIGHT_TO_TOP_OF_CONTAINER
setTop(top)
}
@@ -135,7 +142,7 @@ export function StepContainer(props: StepContainerProps): JSX.Element {
if (stepId != null) {
dispatch(populateForm(stepId))
}
- setStepOverflowMenu(false)
+ setOpenedOverflowMenuId?.(null)
}
const onDeleteClickAction = (): void => {
@@ -168,7 +175,6 @@ export function StepContainer(props: StepContainerProps): JSX.Element {
)
}
}
-
const {
confirm: confirmDelete,
showConfirmation: showDeleteConfirmation,
@@ -242,10 +248,15 @@ export function StepContainer(props: StepContainerProps): JSX.Element {
{
+ onClick={(e: ReactMouseEvent) => {
e.preventDefault()
e.stopPropagation()
- setStepOverflowMenu(prev => !prev)
+ if (openedOverflowMenuId === stepId) {
+ setOpenedOverflowMenuId?.(null)
+ } else {
+ setOpenedOverflowMenuId?.(stepId ?? null)
+ }
+
handleOverflowClick(e)
}}
/>
@@ -262,10 +273,12 @@ export function StepContainer(props: StepContainerProps): JSX.Element {
/>
) : null}
- {stepOverflowMenu && stepId != null
+ {stepId != null &&
+ openedOverflowMenuId === stepId &&
+ setOpenedOverflowMenuId != null
? createPortal(
top: number
- setStepOverflowMenu: React.Dispatch>
+ setOpenedOverflowMenuId: React.Dispatch>
handleEdit: () => void
confirmDelete: () => void
confirmMultiDelete: () => void
@@ -44,7 +44,7 @@ export function StepOverflowMenu(props: StepOverflowMenuProps): JSX.Element {
stepId,
menuRootRef,
top,
- setStepOverflowMenu,
+ setOpenedOverflowMenuId,
handleEdit,
confirmDelete,
confirmMultiDelete,
@@ -91,7 +91,7 @@ export function StepOverflowMenu(props: StepOverflowMenuProps): JSX.Element {
ref={menuRootRef}
zIndex={12}
top={top}
- left="19.5rem"
+ left="18.75rem"
position={POSITION_ABSOLUTE}
whiteSpace={NO_WRAP}
borderRadius={BORDERS.borderRadius8}
@@ -109,7 +109,7 @@ export function StepOverflowMenu(props: StepOverflowMenuProps): JSX.Element {
disabled={batchEditFormHasUnstagedChanges}
onClick={() => {
duplicateMultipleSteps()
- setStepOverflowMenu(false)
+ setOpenedOverflowMenuId(null)
}}
>
{t('duplicate_steps')}
@@ -118,7 +118,7 @@ export function StepOverflowMenu(props: StepOverflowMenuProps): JSX.Element {
}
content={
-
+
{value ?? t('na')}
}
diff --git a/robot-server/robot_server/persistence/tables/schema_7.py b/robot-server/robot_server/persistence/tables/schema_7.py
index 1690298007f..9f0c2879533 100644
--- a/robot-server/robot_server/persistence/tables/schema_7.py
+++ b/robot-server/robot_server/persistence/tables/schema_7.py
@@ -207,7 +207,14 @@ class DataFileSourceSQLEnum(enum.Enum):
sqlalchemy.Column("index_in_run", sqlalchemy.Integer, nullable=False),
sqlalchemy.Column("command_id", sqlalchemy.String, nullable=False),
sqlalchemy.Column("command", sqlalchemy.String, nullable=False),
- sqlalchemy.Column("command_intent", sqlalchemy.String, nullable=False, index=True),
+ sqlalchemy.Column(
+ "command_intent",
+ sqlalchemy.String,
+ # nullable=True to match the underlying SQL, which is nullable because of a bug
+ # in the migration that introduced this column. This is not intended to ever be
+ # null in practice.
+ nullable=True,
+ ),
sqlalchemy.Index(
"ix_run_run_id_command_id", # An arbitrary name for the index.
"run_id",
@@ -251,10 +258,16 @@ class DataFileSourceSQLEnum(enum.Enum):
DataFileSourceSQLEnum,
values_callable=lambda obj: [e.value for e in obj],
validate_strings=True,
- create_constraint=True,
+ # create_constraint=False to match the underlying SQL, which omits
+ # the constraint because of a bug in the migration that introduced this
+ # column. This is not intended to ever have values other than those in
+ # DataFileSourceSQLEnum.
+ create_constraint=False,
),
- index=True,
- nullable=False,
+ # nullable=True to match the underlying SQL, which is nullable because of a bug
+ # in the migration that introduced this column. This is not intended to ever be
+ # null in practice.
+ nullable=True,
),
)
diff --git a/robot-server/tests/persistence/test_tables.py b/robot-server/tests/persistence/test_tables.py
index 9c069157144..642d2506e93 100644
--- a/robot-server/tests/persistence/test_tables.py
+++ b/robot-server/tests/persistence/test_tables.py
@@ -109,7 +109,7 @@
index_in_run INTEGER NOT NULL,
command_id VARCHAR NOT NULL,
command VARCHAR NOT NULL,
- command_intent VARCHAR NOT NULL,
+ command_intent VARCHAR,
PRIMARY KEY (row_id),
FOREIGN KEY(run_id) REFERENCES run (id)
)
@@ -121,23 +121,16 @@
CREATE UNIQUE INDEX ix_run_run_id_index_in_run ON run_command (run_id, index_in_run)
""",
"""
- CREATE INDEX ix_data_files_source ON data_files (source)
- """,
- """
CREATE INDEX ix_protocol_protocol_kind ON protocol (protocol_kind)
""",
"""
- CREATE INDEX ix_run_command_command_intent ON run_command (command_intent)
- """,
- """
CREATE TABLE data_files (
id VARCHAR NOT NULL,
name VARCHAR NOT NULL,
file_hash VARCHAR NOT NULL,
created_at DATETIME NOT NULL,
- source VARCHAR(9) NOT NULL,
- PRIMARY KEY (id),
- CONSTRAINT datafilesourcesqlenum CHECK (source IN ('uploaded', 'generated'))
+ source VARCHAR(9),
+ PRIMARY KEY (id)
)
""",
"""
@@ -542,7 +535,7 @@
def _normalize_statement(statement: str) -> str:
- """Fix up the formatting of a SQL statement for easier comparison."""
+ """Fix up the internal formatting of a single SQL statement for easier comparison."""
lines = statement.splitlines()
# Remove whitespace at the beginning and end of each line.
@@ -551,7 +544,10 @@ def _normalize_statement(statement: str) -> str:
# Filter out blank lines.
lines = [line for line in lines if line != ""]
- return "\n".join(lines)
+ # Normalize line breaks to spaces. When we ask SQLite for its schema, it appears
+ # inconsistent in whether it uses spaces or line breaks to separate tokens.
+ # That may have to do with whether `ALTER TABLE` has been used on the table.
+ return " ".join(lines)
@pytest.mark.parametrize(
@@ -598,18 +594,6 @@ def record_statement(
assert set(normalized_actual) == set(normalized_expected)
-# FIXME(mm, 2024-11-12): https://opentrons.atlassian.net/browse/EXEC-827
-#
-# There are at least these mismatches:
-#
-# - `ix_data_files_source` is present in metadata, but not emitted by the migration path
-# - `ix_run_command_command_intent` is present in metadata, but not emitted by the migration path
-# - `data_files.source` is nullable as emitted by the migration path, but not as declared in metadata
-# - `command.command_intent` is nullable as emitted by the migration path, but not as declared in metadata
-# - constraint `datafilesourcesqlenum` is present in metadata, but not not emitted by the migration path
-#
-# Remove this xfail mark when the mismatches are resolved.
-@pytest.mark.xfail(strict=True)
def test_migrated_db_matches_db_created_from_metadata(tmp_path: Path) -> None:
"""Test that the output of migration matches `metadata.create_all()`.