diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/Airflow_project_weather.iml b/.idea/Airflow_project_weather.iml
new file mode 100644
index 0000000..2c80e12
--- /dev/null
+++ b/.idea/Airflow_project_weather.iml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..d67ca6f
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..2d6bae1
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/airflow_env/Include/site/python3.12/greenlet/greenlet.h b/airflow_env/Include/site/python3.12/greenlet/greenlet.h
new file mode 100644
index 0000000..d02a16e
--- /dev/null
+++ b/airflow_env/Include/site/python3.12/greenlet/greenlet.h
@@ -0,0 +1,164 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
+
+/* Greenlet object interface */
+
+#ifndef Py_GREENLETOBJECT_H
+#define Py_GREENLETOBJECT_H
+
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is deprecated and undocumented. It does not change. */
+#define GREENLET_VERSION "1.0.0"
+
+#ifndef GREENLET_MODULE
+#define implementation_ptr_t void*
+#endif
+
+typedef struct _greenlet {
+ PyObject_HEAD
+ PyObject* weakreflist;
+ PyObject* dict;
+ implementation_ptr_t pimpl;
+} PyGreenlet;
+
+#define PyGreenlet_Check(op) (op && PyObject_TypeCheck(op, &PyGreenlet_Type))
+
+
+/* C API functions */
+
+/* Total number of symbols that are exported */
+#define PyGreenlet_API_pointers 12
+
+#define PyGreenlet_Type_NUM 0
+#define PyExc_GreenletError_NUM 1
+#define PyExc_GreenletExit_NUM 2
+
+#define PyGreenlet_New_NUM 3
+#define PyGreenlet_GetCurrent_NUM 4
+#define PyGreenlet_Throw_NUM 5
+#define PyGreenlet_Switch_NUM 6
+#define PyGreenlet_SetParent_NUM 7
+
+#define PyGreenlet_MAIN_NUM 8
+#define PyGreenlet_STARTED_NUM 9
+#define PyGreenlet_ACTIVE_NUM 10
+#define PyGreenlet_GET_PARENT_NUM 11
+
+#ifndef GREENLET_MODULE
+/* This section is used by modules that uses the greenlet C API */
+static void** _PyGreenlet_API = NULL;
+
+# define PyGreenlet_Type \
+ (*(PyTypeObject*)_PyGreenlet_API[PyGreenlet_Type_NUM])
+
+# define PyExc_GreenletError \
+ ((PyObject*)_PyGreenlet_API[PyExc_GreenletError_NUM])
+
+# define PyExc_GreenletExit \
+ ((PyObject*)_PyGreenlet_API[PyExc_GreenletExit_NUM])
+
+/*
+ * PyGreenlet_New(PyObject *args)
+ *
+ * greenlet.greenlet(run, parent=None)
+ */
+# define PyGreenlet_New \
+ (*(PyGreenlet * (*)(PyObject * run, PyGreenlet * parent)) \
+ _PyGreenlet_API[PyGreenlet_New_NUM])
+
+/*
+ * PyGreenlet_GetCurrent(void)
+ *
+ * greenlet.getcurrent()
+ */
+# define PyGreenlet_GetCurrent \
+ (*(PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
+
+/*
+ * PyGreenlet_Throw(
+ * PyGreenlet *greenlet,
+ * PyObject *typ,
+ * PyObject *val,
+ * PyObject *tb)
+ *
+ * g.throw(...)
+ */
+# define PyGreenlet_Throw \
+ (*(PyObject * (*)(PyGreenlet * self, \
+ PyObject * typ, \
+ PyObject * val, \
+ PyObject * tb)) \
+ _PyGreenlet_API[PyGreenlet_Throw_NUM])
+
+/*
+ * PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
+ *
+ * g.switch(*args, **kwargs)
+ */
+# define PyGreenlet_Switch \
+ (*(PyObject * \
+ (*)(PyGreenlet * greenlet, PyObject * args, PyObject * kwargs)) \
+ _PyGreenlet_API[PyGreenlet_Switch_NUM])
+
+/*
+ * PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
+ *
+ * g.parent = new_parent
+ */
+# define PyGreenlet_SetParent \
+ (*(int (*)(PyGreenlet * greenlet, PyGreenlet * nparent)) \
+ _PyGreenlet_API[PyGreenlet_SetParent_NUM])
+
+/*
+ * PyGreenlet_GetParent(PyObject* greenlet)
+ *
+ * return greenlet.parent;
+ *
+ * This could return NULL even if there is no exception active.
+ * If it does not return NULL, you are responsible for decrementing the
+ * reference count.
+ */
+# define PyGreenlet_GetParent \
+ (*(PyGreenlet* (*)(PyGreenlet*)) \
+ _PyGreenlet_API[PyGreenlet_GET_PARENT_NUM])
+
+/*
+ * deprecated, undocumented alias.
+ */
+# define PyGreenlet_GET_PARENT PyGreenlet_GetParent
+
+# define PyGreenlet_MAIN \
+ (*(int (*)(PyGreenlet*)) \
+ _PyGreenlet_API[PyGreenlet_MAIN_NUM])
+
+# define PyGreenlet_STARTED \
+ (*(int (*)(PyGreenlet*)) \
+ _PyGreenlet_API[PyGreenlet_STARTED_NUM])
+
+# define PyGreenlet_ACTIVE \
+ (*(int (*)(PyGreenlet*)) \
+ _PyGreenlet_API[PyGreenlet_ACTIVE_NUM])
+
+
+
+
+/* Macro that imports greenlet and initializes C API */
+/* NOTE: This has actually moved to ``greenlet._greenlet._C_API``, but we
+ keep the older definition to be sure older code that might have a copy of
+ the header still works. */
+# define PyGreenlet_Import() \
+ { \
+ _PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
+ }
+
+#endif /* GREENLET_MODULE */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_GREENLETOBJECT_H */
diff --git a/airflow_env/Scripts/Activate.ps1 b/airflow_env/Scripts/Activate.ps1
new file mode 100644
index 0000000..d7fe51b
--- /dev/null
+++ b/airflow_env/Scripts/Activate.ps1
@@ -0,0 +1,502 @@
+<#
+.Synopsis
+Activate a Python virtual environment for the current PowerShell session.
+
+.Description
+Pushes the python executable for a virtual environment to the front of the
+$Env:PATH environment variable and sets the prompt to signify that you are
+in a Python virtual environment. Makes use of the command line switches as
+well as the `pyvenv.cfg` file values present in the virtual environment.
+
+.Parameter VenvDir
+Path to the directory that contains the virtual environment to activate. The
+default value for this is the parent of the directory that the Activate.ps1
+script is located within.
+
+.Parameter Prompt
+The prompt prefix to display when this virtual environment is activated. By
+default, this prompt is the name of the virtual environment folder (VenvDir)
+surrounded by parentheses and followed by a single space (ie. '(.venv) ').
+
+.Example
+Activate.ps1
+Activates the Python virtual environment that contains the Activate.ps1 script.
+
+.Example
+Activate.ps1 -Verbose
+Activates the Python virtual environment that contains the Activate.ps1 script,
+and shows extra information about the activation as it executes.
+
+.Example
+Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
+Activates the Python virtual environment located in the specified location.
+
+.Example
+Activate.ps1 -Prompt "MyPython"
+Activates the Python virtual environment that contains the Activate.ps1 script,
+and prefixes the current prompt with the specified string (surrounded in
+parentheses) while the virtual environment is active.
+
+.Notes
+On Windows, it may be required to enable this Activate.ps1 script by setting the
+execution policy for the user. You can do this by issuing the following PowerShell
+command:
+
+PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
+
+For more information on Execution Policies:
+https://go.microsoft.com/fwlink/?LinkID=135170
+
+#>
+Param(
+ [Parameter(Mandatory = $false)]
+ [String]
+ $VenvDir,
+ [Parameter(Mandatory = $false)]
+ [String]
+ $Prompt
+)
+
+<# Function declarations --------------------------------------------------- #>
+
+<#
+.Synopsis
+Remove all shell session elements added by the Activate script, including the
+addition of the virtual environment's Python executable from the beginning of
+the PATH variable.
+
+.Parameter NonDestructive
+If present, do not remove this function from the global namespace for the
+session.
+
+#>
+function global:deactivate ([switch]$NonDestructive) {
+ # Revert to original values
+
+ # The prior prompt:
+ if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
+ Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
+ Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
+ }
+
+ # The prior PYTHONHOME:
+ if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
+ Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
+ Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
+ }
+
+ # The prior PATH:
+ if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
+ Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
+ Remove-Item -Path Env:_OLD_VIRTUAL_PATH
+ }
+
+ # Just remove the VIRTUAL_ENV altogether:
+ if (Test-Path -Path Env:VIRTUAL_ENV) {
+ Remove-Item -Path env:VIRTUAL_ENV
+ }
+
+ # Just remove VIRTUAL_ENV_PROMPT altogether.
+ if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
+ Remove-Item -Path env:VIRTUAL_ENV_PROMPT
+ }
+
+ # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
+ if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
+ Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
+ }
+
+ # Leave deactivate function in the global namespace if requested:
+ if (-not $NonDestructive) {
+ Remove-Item -Path function:deactivate
+ }
+}
+
+<#
+.Description
+Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
+given folder, and returns them in a map.
+
+For each line in the pyvenv.cfg file, if that line can be parsed into exactly
+two strings separated by `=` (with any amount of whitespace surrounding the =)
+then it is considered a `key = value` line. The left hand string is the key,
+the right hand is the value.
+
+If the value starts with a `'` or a `"` then the first and last character is
+stripped from the value before being captured.
+
+.Parameter ConfigDir
+Path to the directory that contains the `pyvenv.cfg` file.
+#>
+function Get-PyVenvConfig(
+ [String]
+ $ConfigDir
+) {
+ Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
+
+ # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
+ $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
+
+ # An empty map will be returned if no config file is found.
+ $pyvenvConfig = @{ }
+
+ if ($pyvenvConfigPath) {
+
+ Write-Verbose "File exists, parse `key = value` lines"
+ $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
+
+ $pyvenvConfigContent | ForEach-Object {
+ $keyval = $PSItem -split "\s*=\s*", 2
+ if ($keyval[0] -and $keyval[1]) {
+ $val = $keyval[1]
+
+ # Remove extraneous quotations around a string value.
+ if ("'""".Contains($val.Substring(0, 1))) {
+ $val = $val.Substring(1, $val.Length - 2)
+ }
+
+ $pyvenvConfig[$keyval[0]] = $val
+ Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
+ }
+ }
+ }
+ return $pyvenvConfig
+}
+
+
+<# Begin Activate script --------------------------------------------------- #>
+
+# Determine the containing directory of this script
+$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
+$VenvExecDir = Get-Item -Path $VenvExecPath
+
+Write-Verbose "Activation script is located in path: '$VenvExecPath'"
+Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
+Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
+
+# Set values required in priority: CmdLine, ConfigFile, Default
+# First, get the location of the virtual environment, it might not be
+# VenvExecDir if specified on the command line.
+if ($VenvDir) {
+ Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
+}
+else {
+ Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
+ $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
+ Write-Verbose "VenvDir=$VenvDir"
+}
+
+# Next, read the `pyvenv.cfg` file to determine any required value such
+# as `prompt`.
+$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
+
+# Next, set the prompt from the command line, or the config file, or
+# just use the name of the virtual environment folder.
+if ($Prompt) {
+ Write-Verbose "Prompt specified as argument, using '$Prompt'"
+}
+else {
+ Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
+ if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
+ Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
+ $Prompt = $pyvenvCfg['prompt'];
+ }
+ else {
+ Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
+ Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
+ $Prompt = Split-Path -Path $venvDir -Leaf
+ }
+}
+
+Write-Verbose "Prompt = '$Prompt'"
+Write-Verbose "VenvDir='$VenvDir'"
+
+# Deactivate any currently active virtual environment, but leave the
+# deactivate function in place.
+deactivate -nondestructive
+
+# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
+# that there is an activated venv.
+$env:VIRTUAL_ENV = $VenvDir
+
+if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
+
+ Write-Verbose "Setting prompt to '$Prompt'"
+
+ # Set the prompt to include the env name
+ # Make sure _OLD_VIRTUAL_PROMPT is global
+ function global:_OLD_VIRTUAL_PROMPT { "" }
+ Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
+ New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
+
+ function global:prompt {
+ Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
+ _OLD_VIRTUAL_PROMPT
+ }
+ $env:VIRTUAL_ENV_PROMPT = $Prompt
+}
+
+# Clear PYTHONHOME
+if (Test-Path -Path Env:PYTHONHOME) {
+ Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
+ Remove-Item -Path Env:PYTHONHOME
+}
+
+# Add the venv to the PATH
+Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
+$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
+
+# SIG # Begin signature block
+# MIIvIwYJKoZIhvcNAQcCoIIvFDCCLxACAQExDzANBglghkgBZQMEAgEFADB5Bgor
+# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
+# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBnL745ElCYk8vk
+# dBtMuQhLeWJ3ZGfzKW4DHCYzAn+QB6CCE8MwggWQMIIDeKADAgECAhAFmxtXno4h
+# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
+# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
+# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z
+# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
+# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
+# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z
+# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ
+# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s
+# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL
+# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb
+# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3
+# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c
+# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx
+# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0
+# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL
+# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud
+# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf
+# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk
+# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS
+# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK
+# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB
+# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp
+# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg
+# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri
+# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7
+# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5
+# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3
+# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H
+# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G
+# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
+# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0
+# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla
+# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
+# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
+# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C
+# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce
+# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da
+# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T
+# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA
+# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh
+# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM
+# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z
+# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05
+# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY
+# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP
+# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T
+# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD
+# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG
+# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY
+# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj
+# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV
+# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU
+# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN
+# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry
+# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL
+# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf
+# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh
+# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh
+# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV
+# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j
+# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH
+# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC
+# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l
+# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW
+# eE4wggd3MIIFX6ADAgECAhAHHxQbizANJfMU6yMM0NHdMA0GCSqGSIb3DQEBCwUA
+# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE
+# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz
+# ODQgMjAyMSBDQTEwHhcNMjIwMTE3MDAwMDAwWhcNMjUwMTE1MjM1OTU5WjB8MQsw
+# CQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMRIwEAYDVQQHEwlCZWF2ZXJ0b24x
+# IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQDExpQ
+# eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+# ADCCAgoCggIBAKgc0BTT+iKbtK6f2mr9pNMUTcAJxKdsuOiSYgDFfwhjQy89koM7
+# uP+QV/gwx8MzEt3c9tLJvDccVWQ8H7mVsk/K+X+IufBLCgUi0GGAZUegEAeRlSXx
+# xhYScr818ma8EvGIZdiSOhqjYc4KnfgfIS4RLtZSrDFG2tN16yS8skFa3IHyvWdb
+# D9PvZ4iYNAS4pjYDRjT/9uzPZ4Pan+53xZIcDgjiTwOh8VGuppxcia6a7xCyKoOA
+# GjvCyQsj5223v1/Ig7Dp9mGI+nh1E3IwmyTIIuVHyK6Lqu352diDY+iCMpk9Zanm
+# SjmB+GMVs+H/gOiofjjtf6oz0ki3rb7sQ8fTnonIL9dyGTJ0ZFYKeb6BLA66d2GA
+# LwxZhLe5WH4Np9HcyXHACkppsE6ynYjTOd7+jN1PRJahN1oERzTzEiV6nCO1M3U1
+# HbPTGyq52IMFSBM2/07WTJSbOeXjvYR7aUxK9/ZkJiacl2iZI7IWe7JKhHohqKuc
+# eQNyOzxTakLcRkzynvIrk33R9YVqtB4L6wtFxhUjvDnQg16xot2KVPdfyPAWd81w
+# tZADmrUtsZ9qG79x1hBdyOl4vUtVPECuyhCxaw+faVjumapPUnwo8ygflJJ74J+B
+# Yxf6UuD7m8yzsfXWkdv52DjL74TxzuFTLHPyARWCSCAbzn3ZIly+qIqDAgMBAAGj
+# ggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNVHQ4E
+# FgQUt/1Teh2XDuUj2WW3siYWJgkZHA8wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM
+# MAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRp
+# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI
+# QTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20v
+# RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex
+# LmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8v
+# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUF
+# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6
+# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWdu
+# aW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZI
+# hvcNAQELBQADggIBABxv4AeV/5ltkELHSC63fXAFYS5tadcWTiNc2rskrNLrfH1N
+# s0vgSZFoQxYBFKI159E8oQQ1SKbTEubZ/B9kmHPhprHya08+VVzxC88pOEvz68nA
+# 82oEM09584aILqYmj8Pj7h/kmZNzuEL7WiwFa/U1hX+XiWfLIJQsAHBla0i7QRF2
+# de8/VSF0XXFa2kBQ6aiTsiLyKPNbaNtbcucaUdn6vVUS5izWOXM95BSkFSKdE45O
+# q3FForNJXjBvSCpwcP36WklaHL+aHu1upIhCTUkzTHMh8b86WmjRUqbrnvdyR2yd
+# I5l1OqcMBjkpPpIV6wcc+KY/RH2xvVuuoHjlUjwq2bHiNoX+W1scCpnA8YTs2d50
+# jDHUgwUo+ciwpffH0Riq132NFmrH3r67VaN3TuBxjI8SIZM58WEDkbeoriDk3hxU
+# 8ZWV7b8AW6oyVBGfM06UgkfMb58h+tJPrFx8VI/WLq1dTqMfZOm5cuclMnUHs2uq
+# rRNtnV8UfidPBL4ZHkTcClQbCoz0UbLhkiDvIS00Dn+BBcxw/TKqVL4Oaz3bkMSs
+# M46LciTeucHY9ExRVt3zy7i149sd+F4QozPqn7FrSVHXmem3r7bjyHTxOgqxRCVa
+# 18Vtx7P/8bYSBeS+WHCKcliFCecspusCDSlnRUjZwyPdP0VHxaZg2unjHY3rMYIa
+# tjCCGrICAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
+# Yy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJT
+# QTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAHHxQbizANJfMU6yMM0NHdMA0GCWCGSAFl
+# AwQCAQUAoIHIMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcC
+# AQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBnAZ6P7YvTwq0fbF62
+# o7E75R0LxsW5OtyYiFESQckLhjBcBgorBgEEAYI3AgEMMU4wTKBGgEQAQgB1AGkA
+# bAB0ADoAIABSAGUAbABlAGEAcwBlAF8AdgAzAC4AMQAyAC4AMwBfADIAMAAyADQA
+# MAA0ADAAOQAuADAAMaECgAAwDQYJKoZIhvcNAQEBBQAEggIAhvmA8nPNyn7jYkuO
+# UobHjUZGgjE7xB8BnrDg5IErORsyIbCSQpdJ4oJ4cnEiVFElql5hVsEY6JWfguaj
+# zELkcgfK5etJxPtNSua/FiBbXqitnDNyHtReLTb+u/T5110GDiTMzpytPorKc21h
+# 6VRXrPmjSTp+Nuji0lulPR9KN6Lxua72t/LZYfT83iZD0eP7rnDoLHqoslb5llEV
+# CaKgLZ8ap8l5uDwHqMm4FYvU9BswEcTQ75wD7jFQd5yGpOzht0hWjAgq9C+nI4Uu
+# nygUpyj1XUAw9FaeRYiVtI0+hkmLNSkUELScNsyFSpZEOJWii3nKkRcupSp8YORJ
+# d24/DjkUuNQMzlHDoVX07E8MFnzzGtgftoRilePSS6qer/RC+SHb18ioY4F0l/EU
+# A8xb+ztHHdeR7OuThn4S/1TMCYJdmqUYpIkmAt1dG/eUlkp+R1DY1KdpT71L828L
+# XgWipnS0PJuHSrWb428U7uF439jB2HjI35a5QclApg2UTeDPQvE0GhLPfJyJCYZ8
+# UYLtbOnd82M4pUJvU6NKmfxZuT2OhsXxQPDTwaqdKaVaBupPbsSTC0o58uarJSSi
+# G5pj4NQyyt1IvZmM2ESV/FufDG5/zSoJ+HO5Ah/AV5ikPlgGwzjdY8vG2CSYJ9os
+# kU9LigwvXmSH/4QYoWN7NtCTCAuhghc/MIIXOwYKKwYBBAGCNwMDATGCFyswghcn
+# BgkqhkiG9w0BBwKgghcYMIIXFAIBAzEPMA0GCWCGSAFlAwQCAQUAMHcGCyqGSIb3
+# DQEJEAEEoGgEZjBkAgEBBglghkgBhv1sBwEwMTANBglghkgBZQMEAgEFAAQgOm4M
+# dN4NqIa6dQy8bSjVKj542yV4A8OJPLti6aa7ZLUCEGqMmddBL+N1YSiZhxqcmY0Y
+# DzIwMjQwNDA5MTQ0MTE2WqCCEwkwggbCMIIEqqADAgECAhAFRK/zlJ0IOaa/2z9f
+# 5WEWMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp
+# Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2
+# IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMjMwNzE0MDAwMDAwWhcNMzQxMDEz
+# MjM1OTU5WjBIMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x
+# IDAeBgNVBAMTF0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIzMIICIjANBgkqhkiG9w0B
+# AQEFAAOCAg8AMIICCgKCAgEAo1NFhx2DjlusPlSzI+DPn9fl0uddoQ4J3C9Io5d6
+# OyqcZ9xiFVjBqZMRp82qsmrdECmKHmJjadNYnDVxvzqX65RQjxwg6seaOy+WZuNp
+# 52n+W8PWKyAcwZeUtKVQgfLPywemMGjKg0La/H8JJJSkghraarrYO8pd3hkYhftF
+# 6g1hbJ3+cV7EBpo88MUueQ8bZlLjyNY+X9pD04T10Mf2SC1eRXWWdf7dEKEbg8G4
+# 5lKVtUfXeCk5a+B4WZfjRCtK1ZXO7wgX6oJkTf8j48qG7rSkIWRw69XloNpjsy7p
+# Be6q9iT1HbybHLK3X9/w7nZ9MZllR1WdSiQvrCuXvp/k/XtzPjLuUjT71Lvr1KAs
+# NJvj3m5kGQc3AZEPHLVRzapMZoOIaGK7vEEbeBlt5NkP4FhB+9ixLOFRr7StFQYU
+# 6mIIE9NpHnxkTZ0P387RXoyqq1AVybPKvNfEO2hEo6U7Qv1zfe7dCv95NBB+plwK
+# WEwAPoVpdceDZNZ1zY8SdlalJPrXxGshuugfNJgvOuprAbD3+yqG7HtSOKmYCaFx
+# smxxrz64b5bV4RAT/mFHCoz+8LbH1cfebCTwv0KCyqBxPZySkwS0aXAnDU+3tTbR
+# yV8IpHCj7ArxES5k4MsiK8rxKBMhSVF+BmbTO77665E42FEHypS34lCh8zrTioPL
+# QHsCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYG
+# A1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG
+# SAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAdBgNVHQ4E
+# FgQUpbbvE+fvzdBkodVWqWUxo97V40kwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDov
+# L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1
+# NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYIKwYBBQUH
+# MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZMaHR0cDov
+# L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNI
+# QTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAgRrW3qCp
+# tZgXvHCNT4o8aJzYJf/LLOTN6l0ikuyMIgKpuM+AqNnn48XtJoKKcS8Y3U623mzX
+# 4WCcK+3tPUiOuGu6fF29wmE3aEl3o+uQqhLXJ4Xzjh6S2sJAOJ9dyKAuJXglnSoF
+# eoQpmLZXeY/bJlYrsPOnvTcM2Jh2T1a5UsK2nTipgedtQVyMadG5K8TGe8+c+nji
+# kxp2oml101DkRBK+IA2eqUTQ+OVJdwhaIcW0z5iVGlS6ubzBaRm6zxbygzc0brBB
+# Jt3eWpdPM43UjXd9dUWhpVgmagNF3tlQtVCMr1a9TMXhRsUo063nQwBw3syYnhmJ
+# A+rUkTfvTVLzyWAhxFZH7doRS4wyw4jmWOK22z75X7BC1o/jF5HRqsBV44a/rCcs
+# QdCaM0qoNtS5cpZ+l3k4SF/Kwtw9Mt911jZnWon49qfH5U81PAC9vpwqbHkB3NpE
+# 5jreODsHXjlY9HxzMVWggBHLFAx+rrz+pOt5Zapo1iLKO+uagjVXKBbLafIymrLS
+# 2Dq4sUaGa7oX/cR3bBVsrquvczroSUa31X/MtjjA2Owc9bahuEMs305MfR5ocMB3
+# CtQC4Fxguyj/OOVSWtasFyIjTvTs0xf7UGv/B3cfcZdEQcm4RtNsMnxYL2dHZeUb
+# c7aZ+WssBkbvQR7w8F/g29mtkIBEr4AQQYowggauMIIElqADAgECAhAHNje3JFR8
+# 2Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
+# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV
+# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0z
+# NzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
+# SW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1
+# NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+# AQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI
+# 82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9
+# xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ
+# 3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5Emfv
+# DqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDET
+# qVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHe
+# IhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jo
+# n7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ
+# 9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/T
+# Xkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJg
+# o1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkw
+# EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+e
+# yG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQD
+# AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEF
+# BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRw
+# Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy
+# dDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln
+# aUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglg
+# hkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGw
+# GC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0
+# MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1D
+# X+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw
+# 1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY
+# +/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0I
+# SQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr
+# 5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7y
+# Rp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDop
+# hrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/
+# AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMO
+# Hds3OBqhK/bt1nz8MIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkq
+# hkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
+# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBB
+# c3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5
+# WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
+# ExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJv
+# b3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1K
+# PDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2r
+# snnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C
+# 8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBf
+# sXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
+# QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8
+# rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaY
+# dj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+
+# wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw
+# ++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+N
+# P8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7F
+# wI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUw
+# AwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAU
+# Reuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEB
+# BG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsG
+# AQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1
+# cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRp
+# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAow
+# CDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/
+# Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLe
+# JLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE
+# 1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9Hda
+# XFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbO
+# byMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYID
+# djCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
+# Yy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYg
+# VGltZVN0YW1waW5nIENBAhAFRK/zlJ0IOaa/2z9f5WEWMA0GCWCGSAFlAwQCAQUA
+# oIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcN
+# MjQwNDA5MTQ0MTE2WjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBRm8CsywsLJD4Jd
+# zqqKycZPGZzPQDAvBgkqhkiG9w0BCQQxIgQgZm7KOZQwUzSPGy0QMkwOOcWaG+w5
+# Nm03VWlT93Aec3QwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQg0vbkbe10IszR1EBX
+# aEE2b4KK2lWarjMWr00amtQMeCgwDQYJKoZIhvcNAQEBBQAEggIATk+R26sfZdRy
+# JMi4Ei4Xaj5TwNTbaUxG2P3ggvT5YpIxZobFK2OohvHFyr8g3ipihMeFc4LdruGS
+# y/8GNua9BnUIYHBXMaxEtxYtiIs32a1R73VSoL/RHVXt/kNI0818/wVOI1aCZdt5
+# MJpjiopPNuneZqH5iym6URk1bvrKlWMFhgA8VggbqQwKiqEtVM7Fy744tuDQjqvE
+# 5TG0Ts298gWzsDnwknFei8RKrbCsr+TRIQ5mWvs9zIBo6d2Rs+JMclGjTwJ71o50
+# Tcq7LgVDldWXARib9mQJmagw+y5LkG66W8I+i1mwQ/9Ur2Lrwnophg7F1HkODXI+
+# 7i3qeNDmnZLXiQM2WTsZ8OlEygAbFtE+ue4ucwFAMbh+1DRCOuwQoN2JMFGNtcj5
+# cbhBBb7am6mYGzg7sGvM7inLEKRV+pqJx1gV/SG+DIVQrHzdlvWTdRmJHIDBMqxr
+# fpnulV80FMuiBJXvKU0RYEgQHw9QDyUNhdQeXSjBd9myt0EW2WyJLY3cYzjmZE1A
+# AcQePJfMbMfYuIBtz7rIXZKNL7/wznLalKxS4aulS7chi5qRiaPJG3lFhlMx//cD
+# 91DxPlbbpCymSjO+3aMRAZyEXjmpHPbROZDSkqLXFf8OYcw4uUZLPLxjbmbZM1hH
+# dz3vPpscd6J1Tz93GwJu/8fZvMEYDjo=
+# SIG # End signature block
diff --git a/airflow_env/Scripts/activate b/airflow_env/Scripts/activate
new file mode 100644
index 0000000..8775c5b
--- /dev/null
+++ b/airflow_env/Scripts/activate
@@ -0,0 +1,70 @@
+# This file must be used with "source bin/activate" *from bash*
+# You cannot run it directly
+
+deactivate () {
+ # reset old environment variables
+ if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
+ PATH="${_OLD_VIRTUAL_PATH:-}"
+ export PATH
+ unset _OLD_VIRTUAL_PATH
+ fi
+ if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
+ PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
+ export PYTHONHOME
+ unset _OLD_VIRTUAL_PYTHONHOME
+ fi
+
+ # Call hash to forget past commands. Without forgetting
+ # past commands the $PATH changes we made may not be respected
+ hash -r 2> /dev/null
+
+ if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
+ PS1="${_OLD_VIRTUAL_PS1:-}"
+ export PS1
+ unset _OLD_VIRTUAL_PS1
+ fi
+
+ unset VIRTUAL_ENV
+ unset VIRTUAL_ENV_PROMPT
+ if [ ! "${1:-}" = "nondestructive" ] ; then
+ # Self destruct!
+ unset -f deactivate
+ fi
+}
+
+# unset irrelevant variables
+deactivate nondestructive
+
+# on Windows, a path can contain colons and backslashes and has to be converted:
+if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
+ # transform D:\path\to\venv to /d/path/to/venv on MSYS
+ # and to /cygdrive/d/path/to/venv on Cygwin
+ export VIRTUAL_ENV=$(cygpath "C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env")
+else
+ # use the path as-is
+ export VIRTUAL_ENV="C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env"
+fi
+
+_OLD_VIRTUAL_PATH="$PATH"
+PATH="$VIRTUAL_ENV/Scripts:$PATH"
+export PATH
+
+# unset PYTHONHOME if set
+# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
+# could use `if (set -u; : $PYTHONHOME) ;` in bash
+if [ -n "${PYTHONHOME:-}" ] ; then
+ _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
+ unset PYTHONHOME
+fi
+
+if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
+ _OLD_VIRTUAL_PS1="${PS1:-}"
+ PS1="(airflow_env) ${PS1:-}"
+ export PS1
+ VIRTUAL_ENV_PROMPT="(airflow_env) "
+ export VIRTUAL_ENV_PROMPT
+fi
+
+# Call hash to forget past commands. Without forgetting
+# past commands the $PATH changes we made may not be respected
+hash -r 2> /dev/null
diff --git a/airflow_env/Scripts/activate-global-python-argcomplete b/airflow_env/Scripts/activate-global-python-argcomplete
new file mode 100644
index 0000000..a14a1d5
--- /dev/null
+++ b/airflow_env/Scripts/activate-global-python-argcomplete
@@ -0,0 +1,154 @@
+#!C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env\Scripts\python.exe
+# PYTHON_ARGCOMPLETE_OK
+
+# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors.
+# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
+
+"""
+Activate the generic bash-completion script or zsh completion autoload function for the argcomplete module.
+"""
+
+import argparse
+import os
+import shutil
+import site
+import subprocess
+import sys
+
+import argcomplete
+
+zsh_shellcode = """
+# Begin added by argcomplete
+fpath=( {zsh_fpath} "${{fpath[@]}}" )
+# End added by argcomplete
+"""
+
+bash_shellcode = """
+# Begin added by argcomplete
+source "{activator}"
+# End added by argcomplete
+"""
+
+
+def get_local_dir():
+ try:
+ return subprocess.check_output(["brew", "--prefix"]).decode().strip()
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ return "/usr/local"
+
+
+def get_zsh_system_dir():
+ return f"{get_local_dir()}/share/zsh/site-functions"
+
+
+def get_bash_system_dir():
+ if "BASH_COMPLETION_COMPAT_DIR" in os.environ:
+ return os.environ["BASH_COMPLETION_COMPAT_DIR"]
+ elif sys.platform == "darwin":
+ return f"{get_local_dir()}/etc/bash_completion.d" # created by homebrew
+ else:
+ return "/etc/bash_completion.d" # created by bash-completion
+
+
+def get_activator_dir():
+ return os.path.join(os.path.abspath(os.path.dirname(argcomplete.__file__)), "bash_completion.d")
+
+
+def get_activator_path():
+ return os.path.join(get_activator_dir(), "_python-argcomplete")
+
+
+def install_to_destination(dest):
+ activator = get_activator_path()
+ if dest == "-":
+ with open(activator) as fh:
+ sys.stdout.write(fh.read())
+ return
+ destdir = os.path.dirname(dest)
+ if not os.path.exists(destdir):
+ try:
+ os.makedirs(destdir, exist_ok=True)
+ except Exception as e:
+ parser.error(f"path {destdir} does not exist and could not be created: {e}")
+ try:
+ print(f"Installing {activator} to {dest}...", file=sys.stderr)
+ shutil.copy(activator, dest)
+ print("Installed.", file=sys.stderr)
+ except Exception as e:
+ parser.error(
+ f"while installing to {dest}: {e}. Please run this command using sudo, or see --help for more options."
+ )
+
+
+def get_consent():
+ if args.yes is True:
+ return True
+ while True:
+ res = input("OK to proceed? [y/n] ")
+ if res.lower() not in {"y", "n", "yes", "no"}:
+ print('Please answer "yes" or "no".', file=sys.stderr)
+ elif res.lower() in {"y", "yes"}:
+ return True
+ else:
+ return False
+
+
+def append_to_config_file(path, shellcode):
+ if os.path.exists(path):
+ with open(path, 'r') as fh:
+ if shellcode in fh.read():
+ print(f"The code already exists in the file {path}.", file=sys.stderr)
+ return
+ print(f"argcomplete needs to append to the file {path}. The following code will be appended:", file=sys.stderr)
+ for line in shellcode.splitlines():
+ print(">", line, file=sys.stderr)
+ if not get_consent():
+ print("Not added.", file=sys.stderr)
+ return
+ print(f"Adding shellcode to {path}...", file=sys.stderr)
+ with open(path, "a") as fh:
+ fh.write(shellcode)
+ print("Added.", file=sys.stderr)
+
+
+def link_user_rcfiles():
+ # TODO: warn if running as superuser
+ zsh_rcfile = os.path.join(os.path.expanduser(os.environ.get("ZDOTDIR", "~")), ".zshenv")
+ append_to_config_file(zsh_rcfile, zsh_shellcode.format(zsh_fpath=get_activator_dir()))
+
+ bash_completion_user_file = os.path.expanduser("~/.bash_completion")
+ append_to_config_file(bash_completion_user_file, bash_shellcode.format(activator=get_activator_path()))
+
+
+parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
+parser.add_argument("-y", "--yes", help="automatically answer yes for all questions", action="store_true")
+parser.add_argument("--dest", help='Specify the shell completion modules directory to install into, or "-" for stdout')
+parser.add_argument("--user", help="Install into user directory", action="store_true")
+argcomplete.autocomplete(parser)
+args = parser.parse_args()
+destinations = []
+
+if args.dest:
+ if args.dest != "-" and not os.path.exists(args.dest):
+ parser.error(f"directory {args.dest} was specified via --dest, but it does not exist")
+ destinations.append(args.dest)
+elif site.ENABLE_USER_SITE and site.USER_SITE in argcomplete.__file__:
+ print(
+ "Argcomplete was installed in the user site local directory. Defaulting to user installation.", file=sys.stderr
+ )
+ link_user_rcfiles()
+elif sys.prefix != sys.base_prefix:
+ print("Argcomplete was installed in a virtual environment. Defaulting to user installation.", file=sys.stderr)
+ link_user_rcfiles()
+elif args.user:
+ link_user_rcfiles()
+else:
+ print("Defaulting to system-wide installation.", file=sys.stderr)
+ destinations.append(f"{get_zsh_system_dir()}/_python-argcomplete")
+ destinations.append(f"{get_bash_system_dir()}/python-argcomplete")
+
+for destination in destinations:
+ install_to_destination(destination)
+
+if args.dest is None:
+ print("Please restart your shell or source the installed file to activate it.", file=sys.stderr)
diff --git a/airflow_env/Scripts/activate.bat b/airflow_env/Scripts/activate.bat
new file mode 100644
index 0000000..9f01bdf
--- /dev/null
+++ b/airflow_env/Scripts/activate.bat
@@ -0,0 +1,34 @@
+@echo off
+
+rem This file is UTF-8 encoded, so we need to update the current code page while executing it
+for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do (
+ set _OLD_CODEPAGE=%%a
+)
+if defined _OLD_CODEPAGE (
+ "%SystemRoot%\System32\chcp.com" 65001 > nul
+)
+
+set VIRTUAL_ENV=C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env
+
+if not defined PROMPT set PROMPT=$P$G
+
+if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT%
+if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%
+
+set _OLD_VIRTUAL_PROMPT=%PROMPT%
+set PROMPT=(airflow_env) %PROMPT%
+
+if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%
+set PYTHONHOME=
+
+if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
+if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH%
+
+set PATH=%VIRTUAL_ENV%\Scripts;%PATH%
+set VIRTUAL_ENV_PROMPT=(airflow_env)
+
+:END
+if defined _OLD_CODEPAGE (
+ "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul
+ set _OLD_CODEPAGE=
+)
diff --git a/airflow_env/Scripts/airflow.exe b/airflow_env/Scripts/airflow.exe
new file mode 100644
index 0000000..d210090
Binary files /dev/null and b/airflow_env/Scripts/airflow.exe differ
diff --git a/airflow_env/Scripts/alembic.exe b/airflow_env/Scripts/alembic.exe
new file mode 100644
index 0000000..21187d1
Binary files /dev/null and b/airflow_env/Scripts/alembic.exe differ
diff --git a/airflow_env/Scripts/connexion.exe b/airflow_env/Scripts/connexion.exe
new file mode 100644
index 0000000..67f2e80
Binary files /dev/null and b/airflow_env/Scripts/connexion.exe differ
diff --git a/airflow_env/Scripts/deactivate.bat b/airflow_env/Scripts/deactivate.bat
new file mode 100644
index 0000000..62a39a7
--- /dev/null
+++ b/airflow_env/Scripts/deactivate.bat
@@ -0,0 +1,22 @@
+@echo off
+
+if defined _OLD_VIRTUAL_PROMPT (
+ set "PROMPT=%_OLD_VIRTUAL_PROMPT%"
+)
+set _OLD_VIRTUAL_PROMPT=
+
+if defined _OLD_VIRTUAL_PYTHONHOME (
+ set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%"
+ set _OLD_VIRTUAL_PYTHONHOME=
+)
+
+if defined _OLD_VIRTUAL_PATH (
+ set "PATH=%_OLD_VIRTUAL_PATH%"
+)
+
+set _OLD_VIRTUAL_PATH=
+
+set VIRTUAL_ENV=
+set VIRTUAL_ENV_PROMPT=
+
+:END
diff --git a/airflow_env/Scripts/docutils.exe b/airflow_env/Scripts/docutils.exe
new file mode 100644
index 0000000..dc3a7ec
Binary files /dev/null and b/airflow_env/Scripts/docutils.exe differ
diff --git a/airflow_env/Scripts/email_validator.exe b/airflow_env/Scripts/email_validator.exe
new file mode 100644
index 0000000..c47af22
Binary files /dev/null and b/airflow_env/Scripts/email_validator.exe differ
diff --git a/airflow_env/Scripts/fabmanager.exe b/airflow_env/Scripts/fabmanager.exe
new file mode 100644
index 0000000..f2bfdeb
Binary files /dev/null and b/airflow_env/Scripts/fabmanager.exe differ
diff --git a/airflow_env/Scripts/flask.exe b/airflow_env/Scripts/flask.exe
new file mode 100644
index 0000000..4466600
Binary files /dev/null and b/airflow_env/Scripts/flask.exe differ
diff --git a/airflow_env/Scripts/get_gprof b/airflow_env/Scripts/get_gprof
new file mode 100644
index 0000000..e208457
--- /dev/null
+++ b/airflow_env/Scripts/get_gprof
@@ -0,0 +1,75 @@
+#!C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env\Scripts\python.exe
+#
+# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
+# Copyright (c) 2008-2016 California Institute of Technology.
+# Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
+# License: 3-clause BSD. The full license text is available at:
+# - https://github.com/uqfoundation/dill/blob/master/LICENSE
+'''
+build profile graph for the given instance
+
+running:
+ $ get_gprof
+
+executes:
+ gprof2dot -f pstats .prof | dot -Tpng -o .call.png
+
+where:
+ are arguments for gprof2dot, such as "-n 5 -e 5"
+ is code to create the instance to profile
+ is the class of the instance (i.e. type(instance))
+
+For example:
+ $ get_gprof -n 5 -e 1 "import numpy; numpy.array([1,2])"
+
+will create 'ndarray.call.png' with the profile graph for numpy.array([1,2]),
+where '-n 5' eliminates nodes below 5% threshold, similarly '-e 1' eliminates
+edges below 1% threshold
+'''
+
+if __name__ == "__main__":
+ import sys
+ if len(sys.argv) < 2:
+ print ("Please provide an object instance (e.g. 'import math; math.pi')")
+ sys.exit()
+ # grab args for gprof2dot
+ args = sys.argv[1:-1]
+ args = ' '.join(args)
+ # last arg builds the object
+ obj = sys.argv[-1]
+ obj = obj.split(';')
+ # multi-line prep for generating an instance
+ for line in obj[:-1]:
+ exec(line)
+ # one-line generation of an instance
+ try:
+ obj = eval(obj[-1])
+ except Exception:
+ print ("Error processing object instance")
+ sys.exit()
+
+ # get object 'name'
+ objtype = type(obj)
+ name = getattr(objtype, '__name__', getattr(objtype, '__class__', objtype))
+
+ # profile dumping an object
+ import dill
+ import os
+ import cProfile
+ #name = os.path.splitext(os.path.basename(__file__))[0]
+ cProfile.run("dill.dumps(obj)", filename="%s.prof" % name)
+ msg = "gprof2dot -f pstats %s %s.prof | dot -Tpng -o %s.call.png" % (args, name, name)
+ try:
+ res = os.system(msg)
+ except Exception:
+ print ("Please verify install of 'gprof2dot' to view profile graphs")
+ if res:
+ print ("Please verify install of 'gprof2dot' to view profile graphs")
+
+ # get stats
+ f_prof = "%s.prof" % name
+ import pstats
+ stats = pstats.Stats(f_prof, stream=sys.stdout)
+ stats.strip_dirs().sort_stats('cumtime')
+ stats.print_stats(20) #XXX: save to file instead of print top 20?
+ os.remove(f_prof)
diff --git a/airflow_env/Scripts/get_objgraph b/airflow_env/Scripts/get_objgraph
new file mode 100644
index 0000000..425a6f6
--- /dev/null
+++ b/airflow_env/Scripts/get_objgraph
@@ -0,0 +1,54 @@
+#!C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env\Scripts\python.exe
+#
+# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
+# Copyright (c) 2008-2016 California Institute of Technology.
+# Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
+# License: 3-clause BSD. The full license text is available at:
+# - https://github.com/uqfoundation/dill/blob/master/LICENSE
+"""
+display the reference paths for objects in ``dill.types`` or a .pkl file
+
+Notes:
+ the generated image is useful in showing the pointer references in
+ objects that are or can be pickled. Any object in ``dill.objects``
+ listed in ``dill.load_types(picklable=True, unpicklable=True)`` works.
+
+Examples::
+
+ $ get_objgraph ArrayType
+ Image generated as ArrayType.png
+"""
+
+import dill as pickle
+#pickle.debug.trace(True)
+#import pickle
+
+# get all objects for testing
+from dill import load_types
+load_types(pickleable=True,unpickleable=True)
+from dill import objects
+
+if __name__ == "__main__":
+ import sys
+ if len(sys.argv) != 2:
+ print ("Please provide exactly one file or type name (e.g. 'IntType')")
+ msg = "\n"
+ for objtype in list(objects.keys())[:40]:
+ msg += objtype + ', '
+ print (msg + "...")
+ else:
+ objtype = str(sys.argv[-1])
+ try:
+ obj = objects[objtype]
+ except KeyError:
+ obj = pickle.load(open(objtype,'rb'))
+ import os
+ objtype = os.path.splitext(objtype)[0]
+ try:
+ import objgraph
+ objgraph.show_refs(obj, filename=objtype+'.png')
+ except ImportError:
+ print ("Please install 'objgraph' to view object graphs")
+
+
+# EOF
diff --git a/airflow_env/Scripts/gunicorn.exe b/airflow_env/Scripts/gunicorn.exe
new file mode 100644
index 0000000..b02043a
Binary files /dev/null and b/airflow_env/Scripts/gunicorn.exe differ
diff --git a/airflow_env/Scripts/httpx.exe b/airflow_env/Scripts/httpx.exe
new file mode 100644
index 0000000..644187e
Binary files /dev/null and b/airflow_env/Scripts/httpx.exe differ
diff --git a/airflow_env/Scripts/jsonschema.exe b/airflow_env/Scripts/jsonschema.exe
new file mode 100644
index 0000000..878f685
Binary files /dev/null and b/airflow_env/Scripts/jsonschema.exe differ
diff --git a/airflow_env/Scripts/mako-render.exe b/airflow_env/Scripts/mako-render.exe
new file mode 100644
index 0000000..fbc69b2
Binary files /dev/null and b/airflow_env/Scripts/mako-render.exe differ
diff --git a/airflow_env/Scripts/markdown-it.exe b/airflow_env/Scripts/markdown-it.exe
new file mode 100644
index 0000000..3a67089
Binary files /dev/null and b/airflow_env/Scripts/markdown-it.exe differ
diff --git a/airflow_env/Scripts/normalizer.exe b/airflow_env/Scripts/normalizer.exe
new file mode 100644
index 0000000..3a16012
Binary files /dev/null and b/airflow_env/Scripts/normalizer.exe differ
diff --git a/airflow_env/Scripts/nvd3.exe b/airflow_env/Scripts/nvd3.exe
new file mode 100644
index 0000000..cea7d59
Binary files /dev/null and b/airflow_env/Scripts/nvd3.exe differ
diff --git a/airflow_env/Scripts/pip.exe b/airflow_env/Scripts/pip.exe
new file mode 100644
index 0000000..27a957d
Binary files /dev/null and b/airflow_env/Scripts/pip.exe differ
diff --git a/airflow_env/Scripts/pip3.12.exe b/airflow_env/Scripts/pip3.12.exe
new file mode 100644
index 0000000..27a957d
Binary files /dev/null and b/airflow_env/Scripts/pip3.12.exe differ
diff --git a/airflow_env/Scripts/pip3.exe b/airflow_env/Scripts/pip3.exe
new file mode 100644
index 0000000..27a957d
Binary files /dev/null and b/airflow_env/Scripts/pip3.exe differ
diff --git a/airflow_env/Scripts/pybabel.exe b/airflow_env/Scripts/pybabel.exe
new file mode 100644
index 0000000..f16bf21
Binary files /dev/null and b/airflow_env/Scripts/pybabel.exe differ
diff --git a/airflow_env/Scripts/pygmentize.exe b/airflow_env/Scripts/pygmentize.exe
new file mode 100644
index 0000000..cdf2fb5
Binary files /dev/null and b/airflow_env/Scripts/pygmentize.exe differ
diff --git a/airflow_env/Scripts/python-argcomplete-check-easy-install-script b/airflow_env/Scripts/python-argcomplete-check-easy-install-script
new file mode 100644
index 0000000..3420efd
--- /dev/null
+++ b/airflow_env/Scripts/python-argcomplete-check-easy-install-script
@@ -0,0 +1,63 @@
+#!C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env\Scripts\python.exe
+
+# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors.
+# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
+
+"""
+This script is part of the Python argcomplete package (https://github.com/kislyuk/argcomplete).
+It is used to check if an EASY-INSTALL-SCRIPT wrapper redirects to a script that contains the string
+"PYTHON_ARGCOMPLETE_OK". If you have enabled global completion in argcomplete, the completion hook will run it every
+time you press in your shell.
+
+Usage:
+ python-argcomplete-check-easy-install-script
+"""
+
+import sys
+
+if len(sys.argv) != 2:
+ sys.exit(__doc__)
+
+sys.tracebacklimit = 0
+
+with open(sys.argv[1]) as fh:
+ line1, head = fh.read(1024).split("\n", 1)[:2]
+ if line1.startswith("#") and ("py" in line1 or "Py" in line1):
+ import re
+
+ lines = head.split("\n", 12)
+ for line in lines:
+ if line.startswith("# EASY-INSTALL-SCRIPT"):
+ import pkg_resources
+
+ dist, script = re.match("# EASY-INSTALL-SCRIPT: '(.+)','(.+)'", line).groups()
+ if "PYTHON_ARGCOMPLETE_OK" in pkg_resources.get_distribution(dist).get_metadata("scripts/" + script):
+ exit(0)
+ elif line.startswith("# EASY-INSTALL-ENTRY-SCRIPT"):
+ dist, group, name = re.match("# EASY-INSTALL-ENTRY-SCRIPT: '(.+)','(.+)','(.+)'", line).groups()
+ import pkgutil
+
+ import pkg_resources
+
+ module_name = pkg_resources.get_distribution(dist).get_entry_info(group, name).module_name
+ with open(pkgutil.get_loader(module_name).get_filename()) as mod_fh:
+ if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024):
+ exit(0)
+ elif line.startswith("# EASY-INSTALL-DEV-SCRIPT"):
+ for line2 in lines:
+ if line2.startswith("__file__"):
+ filename = re.match("__file__ = '(.+)'", line2).group(1)
+ with open(filename) as mod_fh:
+ if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024):
+ exit(0)
+ elif line.startswith("# PBR Generated"):
+ module = re.search("from (.*) import", head).groups()[0]
+ import pkgutil
+
+ import pkg_resources
+
+ with open(pkgutil.get_loader(module).get_filename()) as mod_fh:
+ if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024):
+ exit(0)
+
+exit(1)
diff --git a/airflow_env/Scripts/python.exe b/airflow_env/Scripts/python.exe
new file mode 100644
index 0000000..1801c03
Binary files /dev/null and b/airflow_env/Scripts/python.exe differ
diff --git a/airflow_env/Scripts/pythonw.exe b/airflow_env/Scripts/pythonw.exe
new file mode 100644
index 0000000..d193c58
Binary files /dev/null and b/airflow_env/Scripts/pythonw.exe differ
diff --git a/airflow_env/Scripts/register-python-argcomplete b/airflow_env/Scripts/register-python-argcomplete
new file mode 100644
index 0000000..576b26e
--- /dev/null
+++ b/airflow_env/Scripts/register-python-argcomplete
@@ -0,0 +1,71 @@
+#!C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env\Scripts\python.exe
+# PYTHON_ARGCOMPLETE_OK
+
+# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors.
+# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
+
+"""
+Register a Python executable for use with the argcomplete module.
+
+To perform the registration, source the output of this script in your bash shell
+(quote the output to avoid interpolation).
+
+Example:
+
+ $ eval "$(register-python-argcomplete my-favorite-script.py)"
+
+For Tcsh
+
+ $ eval `register-python-argcomplete --shell tcsh my-favorite-script.py`
+
+For Fish
+
+ $ register-python-argcomplete --shell fish my-favourite-script.py > ~/.config/fish/my-favourite-script.py.fish
+"""
+
+import argparse
+import sys
+
+import argcomplete
+
+parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
+
+parser.add_argument(
+ "--no-defaults",
+ dest="use_defaults",
+ action="store_false",
+ default=True,
+ help="when no matches are generated, do not fallback to readline's default completion (affects bash only)",
+)
+parser.add_argument(
+ "--complete-arguments",
+ nargs=argparse.REMAINDER,
+ help="arguments to call complete with; use of this option discards default options (affects bash only)",
+)
+parser.add_argument(
+ "-s",
+ "--shell",
+ choices=("bash", "zsh", "tcsh", "fish", "powershell"),
+ default="bash",
+ help="output code for the specified shell",
+)
+parser.add_argument(
+ "-e", "--external-argcomplete-script", help="external argcomplete script for auto completion of the executable"
+)
+
+parser.add_argument("executable", nargs="+", help="executable to completed (when invoked by exactly this name)")
+
+argcomplete.autocomplete(parser)
+
+if len(sys.argv) == 1:
+ parser.print_help()
+ sys.exit(1)
+
+args = parser.parse_args()
+
+
+sys.stdout.write(
+ argcomplete.shellcode(
+ args.executable, args.use_defaults, args.shell, args.complete_arguments, args.external_argcomplete_script
+ )
+)
diff --git a/airflow_env/Scripts/rst2html.exe b/airflow_env/Scripts/rst2html.exe
new file mode 100644
index 0000000..4de48ff
Binary files /dev/null and b/airflow_env/Scripts/rst2html.exe differ
diff --git a/airflow_env/Scripts/rst2html4.exe b/airflow_env/Scripts/rst2html4.exe
new file mode 100644
index 0000000..a5e660d
Binary files /dev/null and b/airflow_env/Scripts/rst2html4.exe differ
diff --git a/airflow_env/Scripts/rst2html5.exe b/airflow_env/Scripts/rst2html5.exe
new file mode 100644
index 0000000..b575f74
Binary files /dev/null and b/airflow_env/Scripts/rst2html5.exe differ
diff --git a/airflow_env/Scripts/rst2latex.exe b/airflow_env/Scripts/rst2latex.exe
new file mode 100644
index 0000000..89ea587
Binary files /dev/null and b/airflow_env/Scripts/rst2latex.exe differ
diff --git a/airflow_env/Scripts/rst2man.exe b/airflow_env/Scripts/rst2man.exe
new file mode 100644
index 0000000..bc8af09
Binary files /dev/null and b/airflow_env/Scripts/rst2man.exe differ
diff --git a/airflow_env/Scripts/rst2odt.exe b/airflow_env/Scripts/rst2odt.exe
new file mode 100644
index 0000000..c0315ba
Binary files /dev/null and b/airflow_env/Scripts/rst2odt.exe differ
diff --git a/airflow_env/Scripts/rst2pseudoxml.exe b/airflow_env/Scripts/rst2pseudoxml.exe
new file mode 100644
index 0000000..327e3fd
Binary files /dev/null and b/airflow_env/Scripts/rst2pseudoxml.exe differ
diff --git a/airflow_env/Scripts/rst2s5.exe b/airflow_env/Scripts/rst2s5.exe
new file mode 100644
index 0000000..bedb920
Binary files /dev/null and b/airflow_env/Scripts/rst2s5.exe differ
diff --git a/airflow_env/Scripts/rst2xetex.exe b/airflow_env/Scripts/rst2xetex.exe
new file mode 100644
index 0000000..09f3269
Binary files /dev/null and b/airflow_env/Scripts/rst2xetex.exe differ
diff --git a/airflow_env/Scripts/rst2xml.exe b/airflow_env/Scripts/rst2xml.exe
new file mode 100644
index 0000000..744ed64
Binary files /dev/null and b/airflow_env/Scripts/rst2xml.exe differ
diff --git a/airflow_env/Scripts/slugify.exe b/airflow_env/Scripts/slugify.exe
new file mode 100644
index 0000000..b50ec7e
Binary files /dev/null and b/airflow_env/Scripts/slugify.exe differ
diff --git a/airflow_env/Scripts/sqlformat.exe b/airflow_env/Scripts/sqlformat.exe
new file mode 100644
index 0000000..7d98ae0
Binary files /dev/null and b/airflow_env/Scripts/sqlformat.exe differ
diff --git a/airflow_env/Scripts/tabulate.exe b/airflow_env/Scripts/tabulate.exe
new file mode 100644
index 0000000..c51e005
Binary files /dev/null and b/airflow_env/Scripts/tabulate.exe differ
diff --git a/airflow_env/Scripts/undill b/airflow_env/Scripts/undill
new file mode 100644
index 0000000..6a2fe6b
--- /dev/null
+++ b/airflow_env/Scripts/undill
@@ -0,0 +1,22 @@
+#!C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env\Scripts\python.exe
+#
+# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
+# Copyright (c) 2008-2016 California Institute of Technology.
+# Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
+# License: 3-clause BSD. The full license text is available at:
+# - https://github.com/uqfoundation/dill/blob/master/LICENSE
+"""
+unpickle the contents of a pickled object file
+
+Examples::
+
+ $ undill hello.pkl
+ ['hello', 'world']
+"""
+
+if __name__ == '__main__':
+ import sys
+ import dill
+ for file in sys.argv[1:]:
+ print (dill.load(open(file,'rb')))
+
diff --git a/airflow_env/pyvenv.cfg b/airflow_env/pyvenv.cfg
new file mode 100644
index 0000000..44debfa
--- /dev/null
+++ b/airflow_env/pyvenv.cfg
@@ -0,0 +1,5 @@
+home = C:\Users\raghu\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0
+include-system-site-packages = false
+version = 3.12.3
+executable = C:\Users\raghu\PycharmProjects\Airflow_project_weather\.venv\Scripts\python.exe
+command = C:\Users\raghu\PycharmProjects\Airflow_project_weather\.venv\Scripts\python.exe -m venv C:\Users\raghu\PycharmProjects\Airflow_project_weather\airflow_env
diff --git a/dags/__init__.py b/dags/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/dags/weather_dag.py b/dags/weather_dag.py
new file mode 100644
index 0000000..69a2ddb
--- /dev/null
+++ b/dags/weather_dag.py
@@ -0,0 +1,104 @@
+from airflow import DAG
+from datetime import timedelta, datetime
+from airflow.providers.http.sensors.http import HttpSensor
+import json
+from airflow.providers.http.operators.http import SimpleHttpOperator
+from airflow.operators.python import PythonOperator
+import pandas as pd
+
+
+def kelvin_to_fahrenheit(temp_in_kelvin):
+ # Converts temperature from Kelvin to Fahrenheit
+ temp_in_fahrenheit = (temp_in_kelvin - 273.15) * (9 / 5) + 32
+ return temp_in_fahrenheit
+
+
+def transform_load_data(task_instance):
+ # Extracts the weather data from XCom, transforms it, and loads it to an S3 bucket
+ data = task_instance.xcom_pull(task_ids="extract_weather_data")
+ city = data["name"]
+ weather_description = data["weather"][0]['description']
+ temp_farenheit = kelvin_to_fahrenheit(data["main"]["temp"])
+ feels_like_farenheit = kelvin_to_fahrenheit(data["main"]["feels_like"])
+ min_temp_farenheit = kelvin_to_fahrenheit(data["main"]["temp_min"])
+ max_temp_farenheit = kelvin_to_fahrenheit(data["main"]["temp_max"])
+ pressure = data["main"]["pressure"]
+ humidity = data["main"]["humidity"]
+ wind_speed = data["wind"]["speed"]
+ time_of_record = datetime.utcfromtimestamp(data['dt'] + data['timezone'])
+ sunrise_time = datetime.utcfromtimestamp(data['sys']['sunrise'] + data['timezone'])
+ sunset_time = datetime.utcfromtimestamp(data['sys']['sunset'] + data['timezone'])
+
+ # Create a dictionary with the transformed data
+ transformed_data = {"City": city,
+ "Description": weather_description,
+ "Temperature (F)": temp_farenheit,
+ "Feels Like (F)": feels_like_farenheit,
+ "Minimun Temp (F)": min_temp_farenheit,
+ "Maximum Temp (F)": max_temp_farenheit,
+ "Pressure": pressure,
+ "Humidty": humidity,
+ "Wind Speed": wind_speed,
+ "Time of Record": time_of_record,
+ "Sunrise (Local Time)": sunrise_time,
+ "Sunset (Local Time)": sunset_time
+ }
+
+ # Convert the dictionary to a DataFrame
+ transformed_data_list = [transformed_data]
+ df_data = pd.DataFrame(transformed_data_list)
+
+ # Define AWS credentials
+ aws_credentials = {"key": "xxxxxxxxxxxxx", "secret": "xxxxxxxxxxxxx", "token": "xxxxxxxxxxxxx"}
+
+ # Generate a unique filename based on the current timestamp
+ now = datetime.now()
+ dt_string = now.strftime("%d%m%Y%H%M%S")
+ dt_string = 'current_weather_data_portland_' + dt_string
+
+ # Save the DataFrame to an S3 bucket
+ df_data.to_csv(f"s3://weatherapiairflowbuckets3-yml/{dt_string}.csv", index=False, storage_options=aws_credentials)
+
+
+# Define default arguments for the DAG
+default_args = {
+ 'owner': 'airflow',
+ 'depends_on_past': False,
+ 'start_date': datetime(2023, 1, 8),
+ 'email': ['myemail@domain.com'],
+ 'email_on_failure': False,
+ 'email_on_retry': False,
+ 'retries': 2,
+ 'retry_delay': timedelta(minutes=2)
+}
+
+# Define the DAG
+with DAG('weather_dag',
+ default_args=default_args,
+ schedule_interval='@daily',
+ catchup=False) as dag:
+ # Task to check if the weather API is available
+ is_weather_api_ready = HttpSensor(
+ task_id='is_weather_api_ready',
+ http_conn_id='weathermap_api',
+ endpoint='/data/2.5/weather?q=Portland&APPID=xxxxxxxxxxxxx'
+ )
+
+ # Task to extract weather data from the API
+ extract_weather_data = SimpleHttpOperator(
+ task_id='extract_weather_data',
+ http_conn_id='weathermap_api',
+ endpoint='/data/2.5/weather?q=Portland&APPID=xxxxxxxxxxxxx',
+ method='GET',
+ response_filter=lambda r: json.loads(r.text),
+ log_response=True
+ )
+
+ # Task to transform and load the extracted data
+ transform_load_weather_data = PythonOperator(
+ task_id='transform_load_weather_data',
+ python_callable=transform_load_data
+ )
+
+ # Define task dependencies
+ is_weather_api_ready >> extract_weather_data >> transform_load_weather_data