return {
    Cooldown = {
        Enable = false, -- Personal cooldown between attempts (true = use Time below).
        Time = 30,      -- Seconds between attempts when Cooldown.Enable = true.
    },
    Time = 5,              -- (Legacy) progress-bar duration — unused since the minigame replaced it. Kept for compat with any third-party readers.
    Chance = 75,           -- (Legacy) overall % chance to find anything — superseded by the minigame outcome.
    BaseXP = 8,            -- Base XP awarded on every successful pick.

    -- How many items the server pre-rolls per attempt — randomised each
    -- time within this range. Each rolled item gets one card above the bar
    -- and one green "safe zone" on the bar that the marker must be inside
    -- when the player presses grab. Both bounds inclusive.
    --
    -- Larger ranges add variety ("how many did I get this time?"); a
    -- tight range like { min = 4, max = 4 } pins it to a fixed count.
    MinigameItemRange = { min = 3, max = 5 },

    -- Minigame selector. `Start` runs when a pickpocket attempt begins; it
    -- receives ctx (ctx.items = the server-rolled loot) and returns the
    -- minigame result. Swap the body for any other built-in (see
    -- client/minigame.lua: lockpick, lockpickBar, holdSteady, mash, stealth,
    -- dial, wires, sequence) or your own — without touching the crime code.
    -- Set Enable = false to skip the minigame entirely (auto-success).
    --
    -- Note: only mg.pickpocket reports which slots were grabbed (partial
    -- loot). Other minigames are pass/fail, so on success the player gets all
    -- rolled items, otherwise none.
    Minigame = {
        Enable = true,
        Start = function(ctx)
            return require('client.minigame').pickpocket({
                items               = ctx.items,
                -- Width of each safe zone, in degrees of the marker's full
                -- pass across the bar (360°). Narrower = harder.
                greenArcDeg         = 30,
                -- Marker speed in deg/sec (360° = one full pass); compounds
                -- via the multiplier after each loot.
                rotationSpeedDegSec = 180,
                -- Speed multiplier after each loot (direction also flips).
                speedUpMultiplier   = 1.35,
                -- Time limit in seconds; running out = caught. 0 = no limit.
                timeLimitSec        = 15,
                -- Per-item chance (0..1) a card starts hidden as "???".
                mysteryChance       = 0.5,
            })
        end,
    },
    GiveXPForItems = true, -- Adds the per-item XP value when an item drops.
    GiveXPForCash = true,  -- Adds 1 XP per $ stolen (set false for flat per-pick XP).
    Logging = true,        -- lib.logger entries on success/fail.

    PoliceAlert = {
        Enable = true,
        Chance = 15, -- 0-100 chance an alert fires on a successful pick.
        Send = function()
            local alertMessage = 'Pickpocketing reported'
            print('Police Alert: ' .. alertMessage)

            -- Example: cd_dispatch integration (uncomment to use)
            --[[
            local data = exports['cd_dispatch']:GetPlayerInfo()
            TriggerServerEvent('cd_dispatch:AddNotification', {
                job_table = {'police'},
                coords = data.coords,
                title = '10-15 - Pickpocketing',
                message = ('A %s pickpocketing at %s'):format(data.sex, data.street),
                flash = 0,
                unique_id = data.unique_id,
                sound = 1,
                blip = {
                    sprite = 431,
                    scale = 1.2,
                    colour = 3,
                    flashes = false,
                    text = '911 - Pickpocketing',
                    time = 5,
                    radius = 0,
                }
            })
            --]]
        end,
    },

    -- Tiered loot tables. Each tier carries its own cash range *and* a level-
    -- keyed item bucket (`[1]`, `[2]`, `[3]`). The level bucket is what
    -- `rewards.give` rolls against — same shape as mailbox rewards, so a
    -- single weighted-chance pick lands one item per success.
    --
    -- HOW WEIGHTED CHANCE WORKS
    -- The `chance` field is a *weight*, not a percentage — higher weight =
    -- proportionally more likely. e.g. `chance=20` is twice as likely as
    -- `chance=10` when both are in the same bucket.
    Tiers = {
        low = {
            cash = { min = 4, max = 15 },
            [1] = {
                { item = 'metalscrap', chance = 25, min = 1, max = 2, xp = 1 },
                { item = 'copper',     chance = 15, min = 1, max = 1, xp = 2 },
            },
            [2] = {
                { item = 'metalscrap', chance = 20, min = 2, max = 3, xp = 1 },
                { item = 'copper',     chance = 15, min = 1, max = 2, xp = 2 },
                { item = 'aluminum',   chance = 10, min = 1, max = 1, xp = 3 },
            },
            [3] = {
                { item = 'metalscrap', chance = 18, min = 3, max = 4, xp = 1 },
                { item = 'copper',     chance = 15, min = 2, max = 3, xp = 2 },
                { item = 'aluminum',   chance = 12, min = 1, max = 2, xp = 3 },
                { item = 'steel',      chance = 8,  min = 1, max = 1, xp = 5 },
            },
        },
        medium = {
            cash = { min = 12, max = 32 },
            [1] = {
                { item = 'rolex', chance = 15, min = 1, max = 1, xp = 8 },
                { item = 'phone', chance = 20, min = 1, max = 1, xp = 6 },
            },
            [2] = {
                { item = 'rolex',     chance = 18, min = 1, max = 2, xp = 8  },
                { item = 'phone',     chance = 15, min = 1, max = 1, xp = 6  },
                { item = 'goldchain', chance = 12, min = 1, max = 1, xp = 10 },
            },
            [3] = {
                { item = 'rolex',     chance = 20, min = 1, max = 3, xp = 8  },
                { item = 'phone',     chance = 15, min = 1, max = 2, xp = 6  },
                { item = 'goldchain', chance = 15, min = 1, max = 2, xp = 10 },
                { item = 'laptop',    chance = 10, min = 1, max = 1, xp = 12 },
            },
        },
        high = {
            cash = { min = 25, max = 65 },
            [1] = {
                { item = 'diamond_ring', chance = 12, min = 1, max = 1, xp = 15 },
                { item = 'goldchain',    chance = 18, min = 1, max = 1, xp = 10 },
            },
            [2] = {
                { item = 'diamond_ring', chance = 15, min = 1, max = 1, xp = 15 },
                { item = 'goldchain',    chance = 15, min = 1, max = 2, xp = 10 },
                { item = '10kgoldchain', chance = 10, min = 1, max = 1, xp = 20 },
            },
            [3] = {
                { item = 'diamond_ring', chance = 18, min = 1, max = 2, xp = 15 },
                { item = 'goldchain',    chance = 15, min = 2, max = 3, xp = 10 },
                { item = '10kgoldchain', chance = 12, min = 1, max = 2, xp = 20 },
                { item = 'diamond',      chance = 8,  min = 1, max = 1, xp = 25 },
            },
        },
    },

    -- Zones grouped by tier. Keys are GTA's `GetNameOfZone()` short codes —
    -- they have to match the engine return values exactly. Anything *not*
    -- listed defaults to the `low` tier, so leaving a zone off gives it
    -- the cheapest loot pool rather than no loot at all.
    --
    -- Re-tiering a zone is a one-line move between arrays.
    ZoneTiers = {
        high = {
            'ROCKF',   -- Rockford Hills
            'CHIL',    -- Vinewood Hills
            'HAWICK',  -- Hawick
            'PBLUFF',  -- Pacific Bluffs
            'TONGVAH', -- Tongva Hills
            'RGLEN',   -- Richman Glen
            'RICHM',   -- Richman
            'HORS',    -- Vinewood Racetrack
            'STAD',    -- Maze Bank Arena
            'MOVIE',   -- Richards Majestic
            'BHAMCA',  -- Banham Canyon
            'GOLF',    -- GWC and Golfing Society
        },
        medium = {
            'AIRP',    -- Los Santos International Airport
            'BEACH',   -- Vespucci Beach
            'DELBE',   -- Del Perro Beach
            'DELPE',   -- Del Perro
            'MIRR',    -- Mirror Park
            'MORN',    -- Morningwood
            'ALTA',    -- Alta
            'BURTON',  -- Burton
            'PBOX',    -- Pillbox Hill
            'LEGSQU',  -- Legion Square
            'KOREAT',  -- Little Seoul
            'VINE',    -- Vinewood
            'WVINE',   -- West Vinewood
            'DTVINE',  -- Downtown Vinewood
            'EAST_V',  -- East Vinewood
            'DOWNT',   -- Downtown
            'TEXTI',   -- Textile City
            'HARMO',   -- Harmony
        },
        -- Everything else (Davis, Strawberry, Chamberlain, El Burro, Stab
        -- City, Sandy Shores, Grapeseed, Paleto, the wilds, etc.) falls
        -- through to the `low` tier automatically. Promote a zone by
        -- adding its short code to one of the lists above.
    },
}
