Tuesday, April 21, 2026

 Smallest stable index:

You are given an integer array nums of length n and an integer k.

For each index i, define its instability score as max(nums[0..i]) - min(nums[i..n - 1]).

In other words:

• max(nums[0..i]) is the largest value among the elements from index 0 to index i.

• min(nums[i..n - 1]) is the smallest value among the elements from index i to index n - 1.

An index i is called stable if its instability score is less than or equal to k.

Return the smallest stable index. If no such index exists, return -1.

Example 1:

Input: nums = [5,0,1,4], k = 3

Output: 3

Explanation:

• At index 0: The maximum in [5] is 5, and the minimum in [5, 0, 1, 4] is 0, so the instability score is 5 - 0 = 5.

• At index 1: The maximum in [5, 0] is 5, and the minimum in [0, 1, 4] is 0, so the instability score is 5 - 0 = 5.

• At index 2: The maximum in [5, 0, 1] is 5, and the minimum in [1, 4] is 1, so the instability score is 5 - 1 = 4.

• At index 3: The maximum in [5, 0, 1, 4] is 5, and the minimum in [4] is 4, so the instability score is 5 - 4 = 1.

• This is the first index with an instability score less than or equal to k = 3. Thus, the answer is 3.

Example 2:

Input: nums = [3,2,1], k = 1

Output: -1

Explanation:

• At index 0, the instability score is 3 - 1 = 2.

• At index 1, the instability score is 3 - 1 = 2.

• At index 2, the instability score is 3 - 1 = 2.

• None of these values is less than or equal to k = 1, so the answer is -1.

Example 3:

Input: nums = [0], k = 0

Output: 0

Explanation:

At index 0, the instability score is 0 - 0 = 0, which is less than or equal to k = 0. Therefore, the answer is 0.

Constraints:

• 1 <= nums.length <= 100

• 0 <= nums[i] <= 109

• 0 <= k <= 109

class Solution {

    public int firstStableIndex(int[] nums, int k) {

        long[] scores = new long[nums.length];

        for (int i = 0; i < nums.length; i++) {

            int max = Integer.MIN_VALUE;

            int min = Integer.MAX_VALUE;

            for (int j = 0; j <= i; j++) {

                if (nums[j] > max) {

                    max = nums[j];

                }

            }

            for (int j = i; j < nums.length; j++) {

                if (nums[j] < min) {

                    min = nums[j];

                }

            }

            // System.out.println("max="+max+"&min="+min);

            scores[i] = (long) max - min;

        }

        long min_score = k;

        int min_score_index = -1;

        int first_stable_index = Integer.MIN_VALUE;

        for (int i = 0; i < scores.length; i++) {

            if ( scores[i] <= min_score ) {

                min_score = scores[i];

                min_score_index = i;

                if (first_stable_index == Integer.MIN_VALUE) {

                    first_stable_index = i;

                }

            }

        }

        if (first_stable_index == Integer.MIN_VALUE) {

            first_stable_index = -1;

        }

        return first_stable_index;

    }

}

Test cases:

Case 1:

Input

nums =

[5,0,1,4]

k =

3

Output

3

Expected

3

Case 2:

Input

nums =

[3,2,1]

k =

1

Output

-1

Expected

-1

Case 3:

Input

nums =

[0]

k =

0

Output

0

Expected

0


Sunday, April 19, 2026

 Longest Balanced Substring After One Swap

You are given a binary string s consisting only of characters '0' and '1'.

A string is balanced if it contains an equal number of '0's and '1's.

You can perform at most one swap between any two characters in s. Then, you select a balanced substring from s.

Return an integer representing the maximum length of the balanced substring you can select.

Example 1:

Input: s = "100001"

Output: 4

Explanation:

• Swap "100001". The string becomes "101000".

• Select the substring "101000", which is balanced because it has two '0's and two '1's.

Example 2:

Input: s = "111"

Output: 0

Explanation:

• Choose not to perform any swaps.

• Select the empty substring, which is balanced because it has zero '0's and zero '1's.

Constraints:

• 1 <= s.length <= 105

• s consists only of the characters '0' and '1'

class Solution {

    public int longestBalanced(String s) {

        int max = 0;

        for (int i = 0; i < s.length(); i++) {

            for (int j = i+1; j < s.length(); j++) {

                int count0 = 0;

                int count1 = 0;

                for (int k = i; k <= j; k++) {

                    if (s.charAt(k) == '1') {

                        count1++;

                    } else {

                        count0++;

                    }

                }

                if (count0 == count1 && (j-i+1) > max) {

                    max = j - i + 1;

                }

                else if ((j - i + 1) <= (2 * Math.min(count0, count1) + 1)) {

                    for (int m = 0; m < i; m++) {

                        if (s.charAt(m) == '0' && Math.min(count0, count1) == count0 && (j-i+2) > max) { max = (j-i+2);}

                        if (s.charAt(m) == '1' && Math.min(count0, count1) == count1 && (j-i+2) > max) { max = (j-i+2);}

                    }

                    for (int n = j+1; n < s.length(); n++) {

                        if (s.charAt(n) == '0' && Math.min(count0, count1) == count0 && (j-i+2) > max) { max = (j-i+2);}

                        if (s.charAt(n) == '1' && Math.min(count0, count1) == count1 && (j-i+2) > max) { max = (j-i+2);}

                    }

                } else {

                    // skip

                }

            }

        }

        return max;

    }

}

Test cases:

Case 1:

Input

s =

"100001"

Output

4

Expected

4

Case 2:

Input

s =

"111"

Output

0

Expected

0


Saturday, April 18, 2026

 Detecting structural transitions in continuous visual data streams is a foundational challenge in online video analytics, particularly when the underlying physical process exhibits long periods of repetitive behavior punctuated by brief but critical inflection events. This paper introduces a principled framework for inflection point detection in streaming aerial imagery, motivated by the practical requirement of identifying the four corner events in a drone’s rectangular survey flight path using only the video stream itself, without reliance on GPS, IMU, or external telemetry. The problem is challenging because the majority of the flight consists of highly repetitive, low variation frames captured along straight edges of the rectangle, while the corner events—though visually distinct—occur over a short temporal span and must be detected with 100% recall to ensure the integrity of downstream spatial reasoning tasks such as survey tiling, mosaic alignment, and trajectory reconstruction.

We propose an online clustering and evolution analysis framework inspired by the principles of Ocean (ICDE 2024), which models the streaming feature space using a composite window and tracks the lifecycle of evolving clusters representing stable orientation regimes of the drone. Each frame is transformed into a compact orientation–motion embedding, derived from optical flow based dominant motion direction, homography based rotation cues, and low dimensional CNN features capturing scene layout stability. These embeddings form a continuous stream over which we maintain a set of micro clusters that summarize local density, cohesion, and temporal persistence. The straight line segments of the flight correspond to long lived, high cohesion clusters with stable centroids and minimal drift, while the corners manifest as abrupt transitions in cluster membership, density, and orientation statistics. We formalize these transitions as cluster lifetime inflection points, defined by a conjunction of (i) a sharp change in the dominant orientation component, (ii) a rapid decay in the density of the current cluster, and (iii) the emergence of a new cluster with increasing density and decreasing intra cluster variance.

A key contribution of this work is a thresholding strategy that differentiates true corner events from background repetitive conformance. By modeling the temporal evolution of cluster statistics within a sliding composite window, we derive adaptive thresholds that remain robust to noise, illumination changes, and minor camera jitter while guaranteeing that any genuine orientation transition exceeding a minimal angular displacement is detected. We prove that under mild assumptions about the smoothness of motion along straight edges and the bounded duration of corner rotations, the proposed method achieves perfect recall of all four corners. Extensive conceptual analysis demonstrates that even if the drone’s speed varies, the camera experiences minor vibrations, or the rectangular path is imperfectly executed, the cluster lifetime inflection signature remains uniquely identifiable.

This framework provides a generalizable foundation for online structural change detection in video streams, applicable beyond drone navigation to domains such as autonomous driving, robotic inspection, and surveillance analytics. The corner detection use case serves as a concrete and rigorous anchor for the methodology, ensuring that the proposed approach is both theoretically grounded and practically verifiable. The resulting system is capable of selecting the exact frames corresponding to the four corners from the continuous first person video stream, even when the full tiling of the survey area is not attempted, thereby satisfying the validation requirements of real world aerial analytics pipelines.


Friday, April 17, 2026

 Problem 2:


 Sides of a triangle


You are given a positive integer array sides of length 3.


Determine if there exists a triangle with positive area whose three side lengths are given by the elements of sides.


If such a triangle exists, return an array of three floating-point numbers representing its internal angles (in degrees), sorted in non-decreasing order. Otherwise, return an empty array.


Answers within 10-5 of the actual answer will be accepted.


Example 1:


Input: sides = [3,4,5]


Output: [36.86990,53.13010,90.00000]


Explanation:


You can form a right-angled triangle with side lengths 3, 4, and 5. The internal angles of this triangle are approximately 36.869897646, 53.130102354, and 90 degrees respectively.


Example 2:


Input: sides = [2,4,2]


Output: []


Explanation:


You cannot form a triangle with positive area using side lengths 2, 4, and 2.


Constraints:


• sides.length == 3


• 1 <= sides[i] <= 1000


class Solution {


    public double[] internalAngles(int[] sides) {


        Arrays.sort(sides);


        if (sides[0] + sides[1] > sides[2] &&


            sides[1] + sides[2] > sides[0] &&


            sides[0] + sides[2] > sides[1]) {


            double A = angleFromSides(sides[1], sides[2], sides[0]);


            double B = angleFromSides(sides[0], sides[2], sides[1]);


            double C = angleFromSides(sides[0], sides[1], sides[2]);


            double[] angles = {A, B, C};


            Arrays.sort(angles); // non-decreasing order


            return angles;


        } else {


            return new double[0];


        }


    }


    private static double angleFromSides(int side1, int side2, int opposite) {


        double numerator = (side1 * side1) + (side2 * side2) - (opposite * opposite);


        double denominator = 2.0 * side1 * side2;


        double cosValue = numerator / denominator;


        // Numerical safety: clamp to [-1, 1]


        cosValue = Math.max(-1.0, Math.min(1.0, cosValue));


        return Math.toDegrees(Math.acos(cosValue));


    }


}


Test cases:


Case 0:


Input


sides =


[3,4,5]


Output


[36.86990,53.13010,90.00000]


Expected


[36.86990,53.13010,90.00000]


Case 1:


Input


sides =


[2,4,2]


Output


[]


Expected


[]



Thursday, April 16, 2026

 Problem 1: Find the degree of each vertex.

You are given a 2D integer array matrix of size n x n representing the adjacency matrix of an undirected graph with n vertices labeled from 0 to n - 1.

• matrix[i][j] = 1 indicates that there is an edge between vertices i and j.

• matrix[i][j] = 0 indicates that there is no edge between vertices i and j.

The degree of a vertex is the number of edges connected to it.

Return an integer array ans of size n where ans[i] represents the degree of vertex i.

Example 1:

       1

      / \

     0--2

Input: matrix = [[0,1,1],[1,0,1],[1,1,0]]

Output: [2,2,2]

Explanation:

• Vertex 0 is connected to vertices 1 and 2, so its degree is 2.

• Vertex 1 is connected to vertices 0 and 2, so its degree is 2.

• Vertex 2 is connected to vertices 0 and 1, so its degree is 2.

Thus, the answer is [2, 2, 2].

Example 2:

   0 --- 1

       2cc

Input: matrix = [[0,1,0],[1,0,0],[0,0,0]]

Output: [1,1,0]

Explanation:

• Vertex 0 is connected to vertex 1, so its degree is 1.

• Vertex 1 is connected to vertex 0, so its degree is 1.

• Vertex 2 is not connected to any vertex, so its degree is 0.

Thus, the answer is [1, 1, 0].

Example 3:

Input: matrix = [[0]]

Output: [0]

Explanation:

There is only one vertex and it has no edges connected to it. Thus, the answer is [0].

Constraints:

• 1 <= n == matrix.length == matrix[i].length <= 100

• matrix[i][i] == 0

• matrix[i][j] is either 0 or 1

• matrix[i][j] == matrix[j][i]

class Solution {

    public int[] findDegrees(int[][] matrix) {

        int[] degree = new int[matrix.length];

        for (int i = 0; i < matrix.length; i++) {

            degree[i] = 0;

            for (int j = 0; j < matrix[0].length; j++) {

                if (matrix[i][j] == 1) {

                    degree[i] += 1;

                }

            }

        }

        return degree;

    }

}

Test cases:

Case 0:

Input

matrix =

[[0,1,1],[1,0,1],[1,1,0]]

Output

[2,2,2]

Expected

[2,2,2]

Case 1:

Input

matrix =

[[0,1,0],[1,0,0],[0,0,0]]

Output

[1,1,0]

Expected

[1,1,0]

Case 2:

Input

matrix =

[[0]]

Output

[0]

Expected

[0]


Wednesday, April 15, 2026

 This is a summary of the book titled “The Transformation Myth: Leading Your Organization through Uncertain Times (Management on the Cutting Edge)” written by Anh Nguyen Phillips, Rich Nanda, Jonathan R. Copulsky and Gerald C Kane and published by MIT Press in 2023. The book traces how the COVID‑19 pandemic exposed the fragility of long‑standing organizational assumptions while simultaneously revealing how disruption can become a catalyst for renewal. It argues that the companies that adapted most effectively were those that treated the crisis not as an interruption to be endured but as an inflection point demanding experimentation, reflection and long‑term reinvention. As the authors note, many leaders responded the way clinicians do when confronting acute and chronic conditions, trying rapid fixes where necessary while also laying the groundwork for more durable transformation. This shift in mindset—away from waiting for normalcy to return and toward embracing uncertainty as a space for opportunity—anchors the book’s central claim that growth‑oriented organizations are better positioned to navigate upheaval. As one line in the book puts it, “Leaders and organizations with a growth mindset will be better positioned to cope with disruption.”

From this foundation, the narrative emphasizes that clarity of purpose, values and mission becomes indispensable when teams face ambiguity. Purpose gives people a reason to stay engaged; values ensure that decisions remain principled even under pressure; and mission provides direction when circumstances are shifting too quickly for detailed plans to hold. The authors pair this with a call for rigorous scenario planning, urging leaders to examine long‑term trends, map uncertainties and guard against biases such as the “status quo bias” or the “bandwagon effect,” both mentioned explicitly in the text. By exploring multiple plausible futures and identifying “no regrets moves,” optional bets and transformative opportunities, organizations can avoid being blindsided by change.

The book also stresses that technology alone does not drive transformation; rather, it is the ecosystem of people, partners and capabilities that determines whether digital tools actually solve meaningful problems. Cloud computing becomes a vivid example of this principle, described as a flexible “Lego set” that allows companies to scale, pivot and innovate without heavy fixed investments. Data and machine learning similarly offer advantages only when paired with thoughtful questions, strong data literacy and a culture that values insight over infrastructure.

Finally, the book argues that crises reshape leaders as much as organizations. They heighten empathy, sharpen awareness of customer needs and reveal how deeply habits shape human behavior. As the book notes, “Crises have a way of bringing people together,” and the leaders who rose to the moment during the pandemic did so through authenticity, transparency and a willingness to experiment boldly. The authors conclude that disruption, while destabilizing, can leave organizations more resilient and leaders more human if they approach uncertainty with curiosity, discipline and a commitment to continuous learning.


Tuesday, April 14, 2026

 This is a runbook for migrating GenAI workload comprising of AKS server and langfuse namespaces from one region to another:

1. Step 1: export rg with aztfexport:

#!/usr/bin/env bash

set -euo pipefail

# ---- CONFIG ----

SOURCE_SUBSCRIPTION_ID="<SOURCE_SUBSCRIPTION_ID>"

SOURCE_RG="<SOURCE_GENAI_RG>" # e.g., rg-genai-aks

SOURCE_LOCATION="<SOURCE_REGION>" # e.g., westus2

TARGET_SUBSCRIPTION_ID="<TARGET_SUBSCRIPTION_ID>"

TARGET_LOCATION="eastus2"

SUFFIX="eus2"

TARGET_RG="${SOURCE_RG}-${SUFFIX}"

EXPORT_DIR="./tfexport-${SOURCE_RG}-${SUFFIX}"

# ---- EXPORT FROM SOURCE ----

az account set --subscription "${SOURCE_SUBSCRIPTION_ID}"

mkdir -p "${EXPORT_DIR}"

echo "Exporting all resources from ${SOURCE_RG} using aztfexport..."

aztfexport group \

  --resource-group "${SOURCE_RG}" \

  --output-directory "${EXPORT_DIR}" \

  --append

echo "Export complete: ${EXPORT_DIR}"

# ---- CREATE TARGET RG ----

az account set --subscription "${TARGET_SUBSCRIPTION_ID}"

echo "Creating target RG ${TARGET_RG} in ${TARGET_LOCATION}..."

az group create \

  --name "${TARGET_RG}" \

  --location "${TARGET_LOCATION}" \

  --output none

# ---- REWRITE TF FOR DR ----

echo "Rewriting Terraform for ${TARGET_LOCATION} and -${SUFFIX} names..."

find "${EXPORT_DIR}" -type f -name "*.tf" | while read -r FILE; do

  # Change region

  sed -i "s/\"${SOURCE_LOCATION}\"/\"${TARGET_LOCATION}\"/g" "${FILE}"

  # Append suffix to resource names (simple heuristic; review before apply)

  sed -i -E "s/(name *= *\"[a-zA-Z0-9_-]+)\"/\1-${SUFFIX}\"/g" "${FILE}"

  # Retarget RG references

  sed -i "s/\"${SOURCE_RG}\"/\"${TARGET_RG}\"/g" "${FILE}"

done

echo "Rewrite done. Review ${EXPORT_DIR} and then:"

echo " cd ${EXPORT_DIR}"

echo " terraform init && terraform apply"

2. Step 2: migrate namespaces and workloads:

#!/usr/bin/env bash

set -euo pipefail

# ---- CONFIG ----

SOURCE_SUBSCRIPTION_ID="<SOURCE_SUBSCRIPTION_ID>"

TARGET_SUBSCRIPTION_ID="<TARGET_SUBSCRIPTION_ID>"

SRC_AKS_RG="<SRC_AKS_RG>"

SRC_AKS_NAME="<SRC_AKS_NAME>"

DST_AKS_RG="<DST_AKS_RG>"

DST_AKS_NAME="<DST_AKS_NAME>"

# Namespaces to exclude (system)

EXCLUDE_NS_REGEX="^(kube-system|kube-public|kube-node-lease|gatekeeper-system|azure-arc|default)$"

# ---- GET CONTEXTS ----

echo "Getting kubeconfig for source AKS..."

az account set --subscription "${SOURCE_SUBSCRIPTION_ID}"

az aks get-credentials -g "${SRC_AKS_RG}" -n "${SRC_AKS_NAME}" --overwrite-existing

SRC_CONTEXT=$(kubectl config current-context)

echo "Getting kubeconfig for destination AKS..."

az account set --subscription "${TARGET_SUBSCRIPTION_ID}"

az aks get-credentials -g "${DST_AKS_RG}" -n "${DST_AKS_NAME}" --overwrite-existing

DST_CONTEXT=$(kubectl config current-context)

echo "Source context: ${SRC_CONTEXT}"

echo "Destination context: ${DST_CONTEXT}"

echo ""

# ---- EXPORT NAMESPACES & WORKLOADS FROM SOURCE ----

EXPORT_DIR="./aks-migration-eus2"

mkdir -p "${EXPORT_DIR}"

kubectl config use-context "${SRC_CONTEXT}"

echo "Exporting namespaces and workloads from source cluster..."

NAMESPACES=$(kubectl get ns -o jsonpath='{.items[*].metadata.name}')

for NS in ${NAMESPACES}; do

  if [[ "${NS}" =~ ${EXCLUDE_NS_REGEX} ]]; then

    echo "Skipping system namespace: ${NS}"

    continue

  fi

  NS_DIR="${EXPORT_DIR}/${NS}"

  mkdir -p "${NS_DIR}"

  echo "Exporting namespace: ${NS}"

  # Namespace definition

  kubectl get ns "${NS}" -o yaml > "${NS_DIR}/namespace.yaml"

  # Core workload types (adjust as needed)

  for KIND in deployment statefulset daemonset service configmap secret ingress cronjob job; do

    kubectl get "${KIND}" -n "${NS}" -o yaml > "${NS_DIR}/${KIND}.yaml" || true

  done

done

echo "Export complete: ${EXPORT_DIR}"

# ---- APPLY TO DESTINATION CLUSTER ----

kubectl config use-context "${DST_CONTEXT}"

echo "Applying namespaces and workloads to destination cluster..."

for NS in ${NAMESPACES}; do

  if [[ "${NS}" =~ ${EXCLUDE_NS_REGEX} ]]; then

    continue

  fi

  NS_DIR="${EXPORT_DIR}/${NS}"

  if [[ ! -d "${NS_DIR}" ]]; then

    continue

  fi

  echo "Creating namespace: ${NS}"

  kubectl apply -f "${NS_DIR}/namespace.yaml" || true

  for KIND in deployment statefulset daemonset service configmap secret ingress cronjob job; do

    FILE="${NS_DIR}/${KIND}.yaml"

    if [[ -s "${FILE}" ]]; then

      echo "Applying ${KIND} in ${NS}"

      kubectl apply -n "${NS}" -f "${FILE}"

    fi

  done

done

echo "AKS namespace/workload migration complete."

3. Step 3: find storage accounts with aks subnet allows and migrate data

#!/usr/bin/env bash

set -euo pipefail

# ---- CONFIG ----

SOURCE_SUBSCRIPTION_ID="<SOURCE_SUBSCRIPTION_ID>"

TARGET_SUBSCRIPTION_ID="<TARGET_SUBSCRIPTION_ID>"

SRC_AKS_RG="<SRC_AKS_RG>"

SRC_AKS_NAME="<SRC_AKS_NAME>"

SUFFIX="eus2"

# ---- GET AKS VNET/SUBNETS ----

az account set --subscription "${SOURCE_SUBSCRIPTION_ID}"

AKS_INFO=$(az aks show -g "${SRC_AKS_RG}" -n "${SRC_AKS_NAME}")

# For Azure CNI with custom VNet:

VNET_SUBNET_IDS=$(echo "${AKS_INFO}" | jq -r '.agentPoolProfiles[].vnetSubnetId' | sort -u)

echo "AKS subnets:"

echo "${VNET_SUBNET_IDS}"

echo ""

# ---- FIND MATCHING STORAGE ACCOUNTS ----

echo "Finding storage accounts whose network rules allow these subnets..."

STORAGE_ACCOUNTS=$(az storage account list --query "[].id" -o tsv)

MATCHED_SA=()

for SA_ID in ${STORAGE_ACCOUNTS}; do

  SA_NAME=$(basename "${SA_ID}")

  SA_RG=$(echo "${SA_ID}" | awk -F/ '{print $5}')

  RULES=$(az storage account network-rule list \

    --account-name "${SA_NAME}" \

    --resource-group "${SA_RG}" 2>/dev/null || echo "")

  if [[ -z "${RULES}" ]]; then

    continue

  fi

  for SUBNET_ID in ${VNET_SUBNET_IDS}; do

    if echo "${RULES}" | jq -e --arg sn "${SUBNET_ID}" '.virtualNetworkRules[]?.virtualNetworkResourceId == $sn' >/dev/null 2>&1; then

      echo "Matched storage account: ${SA_NAME} (RG: ${SA_RG}) for subnet: ${SUBNET_ID}"

      MATCHED_SA+=("${SA_ID}")

      break

    fi

  done

done

MATCHED_SA_UNIQ=($(printf "%s\n" "${MATCHED_SA[@]}" | sort -u))

echo ""

echo "Matched storage accounts:"

printf "%s\n" "${MATCHED_SA_UNIQ[@]}"

echo ""

# ---- COPY DATA TO DR STORAGE ACCOUNTS ----

for SA_ID in "${MATCHED_SA_UNIQ[@]}"; do

  SA_NAME=$(basename "${SA_ID}")

  SA_RG=$(echo "${SA_ID}" | awk -F/ '{print $5}')

  TARGET_SA_NAME="${SA_NAME}${SUFFIX}"

  echo "Processing storage account:"

  echo " Source: ${SA_NAME} (RG: ${SA_RG})"

  echo " Target: ${TARGET_SA_NAME}"

  echo ""

  # Source key

  az account set --subscription "${SOURCE_SUBSCRIPTION_ID}"

  SRC_KEY=$(az storage account keys list \

    --account-name "${SA_NAME}" \

    --resource-group "${SA_RG}" \

    --query "[0].value" -o tsv)

  SRC_CONN="DefaultEndpointsProtocol=https;AccountName=${SA_NAME};AccountKey=${SRC_KEY};EndpointSuffix=core.windows.net"

  # Target key

  az account set --subscription "${TARGET_SUBSCRIPTION_ID}"

  # Adjust RG derivation if needed

  TARGET_SA_RG="<TARGET_RG_FOR_${TARGET_SA_NAME}>"

  TGT_KEY=$(az storage account keys list \

    --account-name "${TARGET_SA_NAME}" \

    --resource-group "${TARGET_SA_RG}" \

    --query "[0].value" -o tsv)

  TGT_CONN="DefaultEndpointsProtocol=https;AccountName=${TARGET_SA_NAME};AccountKey=${TGT_KEY};EndpointSuffix=core.windows.net"

  # List containers in source

  az account set --subscription "${SOURCE_SUBSCRIPTION_ID}"

  CONTAINERS=$(az storage container list \

    --connection-string "${SRC_CONN}" \

    --query "[].name" -o tsv)

  for CONT in ${CONTAINERS}; do

    echo "Copying container: ${CONT}"

    SRC_URL="https://${SA_NAME}.blob.core.windows.net/${CONT}"

    TGT_URL="https://${TARGET_SA_NAME}.blob.core.windows.net/${CONT}"

    azcopy copy "${SRC_URL}" "${TGT_URL}" --recursive=true

    echo "Completed copy for container ${CONT}"

  done

done

echo "Storage data copy to DR accounts complete."