ronantakizawa/codereview-bench huggingface dataset:
Repository: meilisearch/meilisearch
File: download-latest.sh (Shell)

Code before:
    return 0
}

success_usage() {
    printf "$GREEN%s\n$DEFAULT" "Meilisearch $latest binary successfully downloaded as '$binary_name' file."
    echo ''
    echo 'Run it:'
    echo '    $ ./meilisearch'
    echo 'Usage:'
    echo '    $ ./meilisearch --help'
}

failure_usage() {
    printf "$RED%s\n$DEFAULT" 'ERROR: Meilisearch binary is not available for your OS distribution or your architecture yet.'
    echo ''
    echo 'However, you can easily compile the binary from the source files.'
    echo 'Follow the steps at the page ("Source" tab): https://docs.meilisearch.com/learn/getting_started/installation.html'
}

# MAIN
latest="$(get_latest)"

if [ "$latest" = '' ]; then
    echo ''
    echo 'Impossible to get the latest stable version of Meilisearch.'
    echo 'Please let us know about this issue: https://github.com/meilisearch/Meilisearch/issues/new/choose'
    exit 1
fi

if ! get_os; then
    failure_usage
    exit 1
fi

if ! get_archi; then
    failure_usage
    exit 1
fi

echo "Downloading Meilisearch binary $latest for $os, architecture $archi..."
case "$os" in
    'windows')
        release_file="meilisearch-$os-$archi.exe"
		binary_name='meilisearch.exe'

        ;;
	*)
		release_file="meilisearch-$os-$archi"
		binary_name='meilisearch'

esac

Review comment (suggestion):
```suggestion
    echo 'Please let us know about this issue: https://github.com/meilisearch/meilisearch/issues/new/choose'
```

Code after:
    return 0
}

success_usage() {
    printf "$GREEN%s\n$DEFAULT" "Meilisearch $latest binary successfully downloaded as '$binary_name' file."
    echo ''
    echo 'Run it:'
    echo '    $ ./meilisearch'
    echo 'Usage:'
    echo '    $ ./meilisearch --help'
}

failure_usage() {
    printf "$RED%s\n$DEFAULT" 'ERROR: Meilisearch binary is not available for your OS distribution or your architecture yet.'
    echo ''
    echo 'However, you can easily compile the binary from the source files.'
    echo 'Follow the steps at the page ("Source" tab): https://docs.meilisearch.com/learn/getting_started/installation.html'
}

# MAIN
latest="$(get_latest)"

if [ "$latest" = '' ]; then
    echo ''
    echo 'Impossible to get the latest stable version of Meilisearch.'
    echo 'Please let us know about this issue: https://github.com/meilisearch/meilisearch/issues/new/choose'
    exit 1
fi

if ! get_os; then
    failure_usage
    exit 1
fi

if ! get_archi; then
    failure_usage
    exit 1
fi

echo "Downloading Meilisearch binary $latest for $os, architecture $archi..."
case "$os" in
    'windows')
        release_file="meilisearch-$os-$archi.exe"
		binary_name='meilisearch.exe'

        ;;
	*)
		release_file="meilisearch-$os-$archi"
		binary_name='meilisearch'

esac
Repository: meilisearch/meilisearch
File: download-latest.sh (Shell)

Code before:
    case "$os_name" in
    'Darwin')
        os='macos'
        ;;
    'Linux')
        os='linux'
        ;;
	'MINGW'*)
        os='windows'
        ;;
    *)
        return 1
    esac
    return 0
}

# Gets the architecture by setting the $archi variable
# Returns 0 in case of success, 1 otherwise.
get_archi() {
    architecture=$(uname -m)
    case "$architecture" in
    'x86_64' | 'amd64' )
        archi='amd64'
        ;;
    'arm64')
        if [ $os -eq 'macos' ]; then # MacOS M1
            archi='amd64'
        else
            archi='aarch64'
        fi
        ;;
    'aarch64')
        archi='aarch64'
        ;;
    *)
        return 1
    esac
    return 0
}

success_usage() {
    printf "$GREEN%s\n$DEFAULT" "Meilisearch $latest binary successfully downloaded as '$binary_name' file."
    echo ''
    echo 'Run it:'
    echo '    $ ./meilisearch'
    echo 'Usage:'
    echo '    $ ./meilisearch --help'
}

failure_usage() {
    printf "$RED%s\n$DEFAULT" 'ERROR: Meilisearch binary is not available for your OS distribution or your architecture yet.'

Review comment (suggestion):
```suggestion
        if [ $os = 'macos' ]; then # MacOS M1
```

I just checked and it seems like `-eq` is here to compare numbers (?) and `=` is used to compare strings.

Code after:
    case "$os_name" in
    'Darwin')
        os='macos'
        ;;
    'Linux')
        os='linux'
        ;;
	'MINGW'*)
        os='windows'
        ;;
    *)
        return 1
    esac
    return 0
}

# Gets the architecture by setting the $archi variable
# Returns 0 in case of success, 1 otherwise.
get_archi() {
    architecture=$(uname -m)
    case "$architecture" in
    'x86_64' | 'amd64' )
        archi='amd64'
        ;;
    'arm64')
        if [ $os = 'macos' ]; then # MacOS M1
            archi='amd64'
        else
            archi='aarch64'
        fi
        ;;
    'aarch64')
        archi='aarch64'
        ;;
    *)
        return 1
    esac
    return 0
}

success_usage() {
    printf "$GREEN%s\n$DEFAULT" "Meilisearch $latest binary successfully downloaded as '$binary_name' file."
    echo ''
    echo 'Run it:'
    echo '    $ ./meilisearch'
    echo 'Usage:'
    echo '    $ ./meilisearch --help'
}

not_available_failure_usage() {
    printf "$RED%s\n$DEFAULT" 'ERROR: Meilisearch binary is not available for your OS distribution or your architecture yet.'
Repository: meilisearch/meilisearch
File: meilisearch-http/src/extractors/sequential_extractor.rs (Rust)

Code before:
#![allow(non_snake_case)]
use std::{future::Future, pin::Pin, task::Poll};

use actix_web::{dev::Payload, FromRequest, Handler, HttpRequest};
use pin_project_lite::pin_project;

/// `SeqHandler` is an actix `Handler` that enforces that extractors errors are returned in the
/// same order as they are defined in the wrapped handler. This is needed because, by default, actix
/// to resolves the extractors concurrently, whereas we always need the authentication extractor to
/// throw first.
#[derive(Clone)]
pub struct SeqHandler<H>(pub H);

pub struct SeqFromRequest<T>(T);

/// This macro implements `FromRequest` for arbitrary arity handler, except for one, which is
/// useless anyway.
macro_rules! gen_seq {
    ($ty:ident; $($T:ident)+) => {
        pin_project! {
            pub struct $ty<$($T: FromRequest), +> {
                $(
                #[pin]
                $T: ExtractFuture<$T::Future, $T, $T::Error>,
                )+
            }
        }

        impl<$($T: FromRequest), +> Future for $ty<$($T),+> {
            type Output = Result<SeqFromRequest<($($T),+)>, actix_web::Error>;

            fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
                let mut this = self.project();


Review comment (security):
```suggestion
/// resolves the extractors concurrently, whereas we always need the authentication extractor to
```

Code after:
#![allow(non_snake_case)]
use std::{future::Future, pin::Pin, task::Poll};

use actix_web::{dev::Payload, FromRequest, Handler, HttpRequest};
use pin_project_lite::pin_project;

/// `SeqHandler` is an actix `Handler` that enforces that extractors errors are returned in the
/// same order as they are defined in the wrapped handler. This is needed because, by default, actix
/// resolves the extractors concurrently, whereas we always need the authentication extractor to
/// throw first.
#[derive(Clone)]
pub struct SeqHandler<H>(pub H);

pub struct SeqFromRequest<T>(T);

/// This macro implements `FromRequest` for arbitrary arity handler, except for one, which is
/// useless anyway.
macro_rules! gen_seq {
    ($ty:ident; $($T:ident)+) => {
        pin_project! {
            pub struct $ty<$($T: FromRequest), +> {
                $(
                #[pin]
                $T: ExtractFuture<$T::Future, $T, $T::Error>,
                )+
            }
        }

        impl<$($T: FromRequest), +> Future for $ty<$($T),+> {
            type Output = Result<SeqFromRequest<($($T),+)>, actix_web::Error>;

            fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
                let mut this = self.project();
Repository: meilisearch/meilisearch
File: meilisearch-http/src/helpers/env.rs (Rust)

Code before:
use meilisearch_lib::milli::heed::Env;
use walkdir::WalkDir;

pub trait EnvSizer {
    fn size(&self) -> u64;
}

impl EnvSizer for Env {
    fn size(&self) -> u64 {
        WalkDir::new(self.path())
            .into_iter()
            .filter_map(|entry| entry.ok())
            .filter_map(|entry| entry.metadata().ok())
            .filter(|metadata| metadata.is_file())
            .fold(0, |acc, m| acc + m.len())
    }
}


Review comment (suggestion):
what about re-exporting `heed` directly, since this is the only thing we need from milli on `meilisearch-http` side
```suggestion
use meilisearch_lib::heed::Env;
```

Code after:
use meilisearch_lib::heed::Env;
use walkdir::WalkDir;

pub trait EnvSizer {
    fn size(&self) -> u64;
}

impl EnvSizer for Env {
    fn size(&self) -> u64 {
        WalkDir::new(self.path())
            .into_iter()
            .filter_map(|entry| entry.ok())
            .filter_map(|entry| entry.metadata().ok())
            .filter(|metadata| metadata.is_file())
            .fold(0, |acc, m| acc + m.len())
    }
}
Repository: meilisearch/meilisearch
File: meilisearch-lib/src/dump/loaders/v4.rs (Rust)

Code before:
use std::path::Path;

use log::info;

use crate::dump::Metadata;
use crate::options::IndexerOpts;

pub fn load_dump(
    meta: Metadata,
    src: impl AsRef<Path>,
    dst: impl AsRef<Path>,
    index_db_size: usize,
    meta_env_size: usize,
    indexing_options: &IndexerOpts,
) -> anyhow::Result<()> {
    info!("Patching dump V4 to dump V5...");

    super::v5::load_dump(
        meta,
        src,
        dst,
        index_db_size,
        meta_env_size,
        indexing_options,
    )
}


Review comment (suggestion):
I know this is useless here, but I think it will ease future merges:

```suggestion
    info!("Patching dump V4 to dump V5...");
    
    let patched_dir = tempdir()?;
    let options = CopyOptions::default();
    
    // Indexes
    dir::copy(src.as_ref().join("indexes"), patched_dir.path(), &options)?;
    
    // Index uuids
    dir::copy(
        src.as_ref().join("index_uuids"),
        patched_dir.path(),
        &options,
    )?;
    
    // Metadata
    fs::copy(
        src.as_ref().join("metadata.json"),
        patched_dir.path().join("metadata.json"),
    )?;
    
    // Updates
    dir::copy(src.as_ref().join("updates"), patched_dir.path(), &options)?;
    
    // Keys
    if src.as_ref().join("keys").exists() {
        fs::copy(src.as_ref().join("keys"), patched_dir.path().join("keys"))?;
    }
```

Code after:
use std::fs;
use std::path::Path;

use fs_extra::dir::{self, CopyOptions};
use log::info;
use tempfile::tempdir;

use crate::dump::Metadata;
use crate::options::IndexerOpts;

pub fn load_dump(
    meta: Metadata,
    src: impl AsRef<Path>,
    dst: impl AsRef<Path>,
    index_db_size: usize,
    meta_env_size: usize,
    indexing_options: &IndexerOpts,
) -> anyhow::Result<()> {
    info!("Patching dump V4 to dump V5...");

    let patched_dir = tempdir()?;
    let options = CopyOptions::default();

    // Indexes
    dir::copy(src.as_ref().join("indexes"), patched_dir.path(), &options)?;

    // Index uuids
    dir::copy(
        src.as_ref().join("index_uuids"),
        patched_dir.path(),
        &options,
    )?;

    // Metadata
    fs::copy(
        src.as_ref().join("metadata.json"),
        patched_dir.path().join("metadata.json"),
    )?;

    // Updates
    dir::copy(src.as_ref().join("updates"), patched_dir.path(), &options)?;

    // Keys
    if src.as_ref().join("keys").exists() {
Repository: meilisearch/meilisearch
File: meilisearch-http/src/routes/tasks.rs (Rust)

Code before:
                None => true,
            };

            let matches_status = match &status {
                Some(statuses) => statuses
                    .iter()
                    .any(|t| task_status_matches_events(t, &task.events)),
                None => true,
            };

            matches_type && matches_status
        });
        Some(filters)
    } else {
        indexes_filters
    };

    // We +1 just to know if there is more after this "page" or not.
    let limit = limit.saturating_add(1);

    let mut tasks_results = meilisearch
        .list_tasks(filters, Some(limit), from)
        .await?
        .into_iter()
        .map(TaskView::from)
        .collect::<Vec<_>>();

    // If we were able to fetch the number +1 tasks we asked
    // it means that there is more to come.
    let next = if tasks_results.len() == limit {
        tasks_results.pop().map(|t| t.uid)
    } else {
        None
    };

    let from = tasks_results.first().map(|t| t.uid);

    let tasks = TaskListView {
        results: tasks_results,
        limit: limit.saturating_sub(1),
        from,
        next,
    };

    Ok(HttpResponse::Ok().json(tasks))
}

async fn get_task(
    meilisearch: GuardedData<ActionPolicy<{ actions::TASKS_GET }>, MeiliSearch>,
    task_id: web::Path<TaskId>,
    req: HttpRequest,

Review comment (suggestion):
```suggestion
    let mut tasks_results: Vec<_> = meilisearch
        .list_tasks(filters, Some(limit), from)
        .await?
        .into_iter()
        .map(TaskView::from)
        .collect();
```

Code after:
                None => true,
            };

            let matches_status = match &status {
                Some(statuses) => statuses
                    .iter()
                    .any(|t| task_status_matches_events(t, &task.events)),
                None => true,
            };

            matches_type && matches_status
        });
        Some(filters)
    } else {
        indexes_filters
    };

    // We +1 just to know if there is more after this "page" or not.
    let limit = limit.saturating_add(1);

    let mut tasks_results: Vec<_> = meilisearch
        .list_tasks(filters, Some(limit), from)
        .await?
        .into_iter()
        .map(TaskView::from)
        .collect();

    // If we were able to fetch the number +1 tasks we asked
    // it means that there is more to come.
    let next = if tasks_results.len() == limit {
        tasks_results.pop().map(|t| t.uid)
    } else {
        None
    };

    let from = tasks_results.first().map(|t| t.uid);

    let tasks = TaskListView {
        results: tasks_results,
        limit: limit.saturating_sub(1),
        from,
        next,
    };

    Ok(HttpResponse::Ok().json(tasks))
}

async fn get_task(
    meilisearch: GuardedData<ActionPolicy<{ actions::TASKS_GET }>, MeiliSearch>,
    task_id: web::Path<TaskId>,
    req: HttpRequest,
Repository: meilisearch/meilisearch
File: meilisearch-lib/src/index_resolver/mod.rs (Rust)

Code before:
        write!(
            f,
            "invalid index uid `{}`, the uid must be an integer \
            or a string containing only alphanumeric characters \
            a-z A-Z 0-9, hyphens - and underscores _.",
            self.invalid_uid,
        )
    }
}

impl Error for IndexUidFormatError {}

impl From<IndexUidFormatError> for IndexResolverError {
    fn from(error: IndexUidFormatError) -> Self {
        Self::BadlyFormatted(error.invalid_uid)
    }
}

impl FromStr for IndexUid {
    type Err = IndexUidFormatError;

    fn from_str(uid: &str) -> std::result::Result<IndexUid, IndexUidFormatError> {
        if !uid
            .chars()
            .all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
            || !(1..=400).contains(&uid.len())
        {
            Err(IndexUidFormatError {
                invalid_uid: uid.to_string(),
            })
        } else {
            Ok(IndexUid(uid.to_string()))
        }
    }
}

pub struct IndexResolver<U, I> {
    index_uuid_store: U,
    index_store: I,
    pub file_store: UpdateFileStore,
}

impl IndexResolver<HeedMetaStore, MapIndexStore> {
    pub fn load_dump(
        src: impl AsRef<Path>,
        dst: impl AsRef<Path>,
        index_db_size: usize,
        env: Arc<Env>,
        indexer_opts: &IndexerOpts,
    ) -> anyhow::Result<()> {
        HeedMetaStore::load_dump(&src, env)?;

Review comment (suggestion):
I understand that this was not the scope of this PR, but I find that this line is not easy to understand, could you change it to something like:

```suggestion
            || uid.len() < 1 || uid.len() > 400
```

Code after:
        write!(
            f,
            "invalid index uid `{}`, the uid must be an integer \
            or a string containing only alphanumeric characters \
            a-z A-Z 0-9, hyphens - and underscores _.",
            self.invalid_uid,
        )
    }
}

impl Error for IndexUidFormatError {}

impl From<IndexUidFormatError> for IndexResolverError {
    fn from(error: IndexUidFormatError) -> Self {
        Self::BadlyFormatted(error.invalid_uid)
    }
}

impl FromStr for IndexUid {
    type Err = IndexUidFormatError;

    fn from_str(uid: &str) -> std::result::Result<IndexUid, IndexUidFormatError> {
        if !uid
            .chars()
            .all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
            || uid.is_empty()
            || uid.len() > 400
        {
            Err(IndexUidFormatError {
                invalid_uid: uid.to_string(),
            })
        } else {
            Ok(IndexUid(uid.to_string()))
        }
    }
}

pub struct IndexResolver<U, I> {
    index_uuid_store: U,
    index_store: I,
    pub file_store: UpdateFileStore,
}

impl IndexResolver<HeedMetaStore, MapIndexStore> {
    pub fn load_dump(
        src: impl AsRef<Path>,
        dst: impl AsRef<Path>,
        index_db_size: usize,
        env: Arc<Env>,
        indexer_opts: &IndexerOpts,
    ) -> anyhow::Result<()> {
Repository: meilisearch/meilisearch
File: .github/scripts/check-release.sh (Shell)

Code before:
#!/bin/sh

# Checking if current tag matches the package version
current_tag=$(echo $GITHUB_REF | tr -d 'refs/tags/v')
file1='meilisearch-auth/Cargo.toml'
file2='meilisearch-http/Cargo.toml'
file3='meilisearch-lib/Cargo.toml'
file4='meilisearch-types/Cargo.toml'
file5='Cargo.lock'

file_tag1=$(grep '^version = ' $file1 | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')
file_tag2=$(grep '^version = ' $file2 | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')
file_tag3=$(grep '^version = ' $file3 | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')
file_tag4=$(grep '^version = ' $file4 | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')
file_tag5=$(grep -A 1 'name = "meilisearch-auth"' $file5 | grep version | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')

if [ "$current_tag" != "$file_tag1" ] || [ "$current_tag" != "$file_tag2" ] || [ "$current_tag" != "$file_tag3" ] || [ "$current_tag" != "$file_tag4" ] || [ "$current_tag" != "$file_tag5" ]; then
  echo "Error: the current tag does not match the version in package file(s)."
  echo "$file1: found $file_tag1 - expected $current_tag"
  echo "$file2: found $file_tag2 - expected $current_tag"
  echo "$file3: found $file_tag3 - expected $current_tag"
  echo "$file4: found $file_tag4 - expected $current_tag"
  echo "$file5: found $file_tag5 - expected $current_tag"
  exit 1
fi

echo 'OK'
exit 0


Review comment (security):
```suggestion

file5=$(grep -A 1 'name = "meilisearch-auth"' $file5 | grep version)

for file in $file1 $file2 $file3 $file4 $file5;
do
    file_tag=$(grep '^version = ' $file | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')
    if [ "$current_tag" != "$file_tag" ]; then
      echo "Error: the current tag does not match the version in package file(s)."
      echo "$file: found $file_tag - expected $current_tag"
      exit 1
    fi
done
```

Maybe we could factorize this code a little bit like that what do you think?

Code after:
#!/bin/sh

# check_tag $current_tag $file_tag $file_name
function check_tag {
  if [ "$1" != "$2" ]; then
      echo "Error: the current tag does not match the version in $3: found $1 - expected $2"
      ret=1
  fi
}

ret=0
current_tag=$(echo $GITHUB_REF | tr -d 'refs/tags/v')

toml_files='*/Cargo.toml'
for toml_file in $toml_files;
do
    file_tag="$(grep '^version = ' $toml_file | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')"
    check_tag $current_tag $file_tag $toml_file
done

lock_file='Cargo.lock'
lock_tag=$(grep -A 1 'name = "meilisearch-auth"' $lock_file | grep version | cut -d '=' -f 2 | tr -d '"' | tr -d ' ')
check_tag $current_tag $lock_tag $lock_file

if [ "$ret" -eq 0 ] ; then
  echo 'OK'
fi
exit $ret
Repository: meilisearch/meilisearch
File: download-latest.sh (Shell)

Code before:
#!/bin/sh

# GLOBALS

# Colors
RED='\033[31m'
GREEN='\033[32m'
DEFAULT='\033[0m'

# Project name
PNAME='meilisearch'

# Version regexp i.e. v[number].[number].[number]
GREP_SEMVER_REGEXP='v\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)$'

# Github API address
GITHUB_API='https://api.github.com/repos/meilisearch/meilisearch/releases'
# Github Release address
GITHUB_REL='https://github.com/meilisearch/meilisearch/releases/download/'

# FUNCTIONS

# semverParseInto and semverLT from: https://github.com/cloudflare/semver_bash/blob/master/semver.sh
# usage: semverParseInto version major minor patch special
# version: the string version
# major, minor, patch, special: will be assigned by the function
semverParseInto() {
    local RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)'
    # MAJOR
    eval $2=`echo $1 | sed -e "s#$RE#\1#"`
    # MINOR
    eval $3=`echo $1 | sed -e "s#$RE#\2#"`
    # PATCH
    eval $4=`echo $1 | sed -e "s#$RE#\3#"`
    # SPECIAL
    eval $5=`echo $1 | sed -e "s#$RE#\4#"`
}

# usage: semverLT version1 version2
semverLT() {
    local MAJOR_A=0
    local MINOR_A=0
    local PATCH_A=0

Review comment (suggestion):
```suggestion
# GitHub API address
GITHUB_API='https://api.github.com/repos/meilisearch/meilisearch/releases'
# GitHub Release address
```

Code after:
#!/bin/sh

# GLOBALS

# Colors
RED='\033[31m'
GREEN='\033[32m'
DEFAULT='\033[0m'

# Project name
PNAME='meilisearch'

# Version regexp i.e. v[number].[number].[number]
GREP_SEMVER_REGEXP='v\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)$'

# GitHub API address
GITHUB_API='https://api.github.com/repos/meilisearch/meilisearch/releases'
# GitHub Release address
GITHUB_REL='https://github.com/meilisearch/meilisearch/releases/download/'

# FUNCTIONS

# semverParseInto and semverLT from: https://github.com/cloudflare/semver_bash/blob/master/semver.sh
# usage: semverParseInto version major minor patch special
# version: the string version
# major, minor, patch, special: will be assigned by the function
semverParseInto() {
    local RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)'
    # MAJOR
    eval $2=`echo $1 | sed -e "s#$RE#\1#"`
    # MINOR
    eval $3=`echo $1 | sed -e "s#$RE#\2#"`
    # PATCH
    eval $4=`echo $1 | sed -e "s#$RE#\3#"`
    # SPECIAL
    eval $5=`echo $1 | sed -e "s#$RE#\4#"`
}

# usage: semverLT version1 version2
semverLT() {
    local MAJOR_A=0
    local MINOR_A=0
    local PATCH_A=0