{"spec_id":"barcode-code128","library":"bokeh","language":"python","code":"\"\"\" anyplot.ai\nbarcode-code128: Code 128 Barcode\nLibrary: bokeh 3.9.0 | Python 3.13.13\nQuality: 88/100 | Updated: 2026-05-21\n\"\"\"\n\nimport os\nimport sys\nimport time\nfrom pathlib import Path\n\n\n# Remove this script's own directory from sys.path so the installed\n# bokeh package is found instead of this file (which is also named bokeh.py).\n_own_dir = os.path.dirname(os.path.realpath(__file__))\nsys.path = [p for p in sys.path if os.path.realpath(p or \".\") != _own_dir]\n\nimport base64\n\nfrom bokeh.embed import file_html\nfrom bokeh.models import ColumnDataSource, HoverTool, Label\nfrom bokeh.plotting import figure\nfrom bokeh.resources import INLINE\nfrom selenium import webdriver\nfrom selenium.webdriver.chrome.options import Options\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nACCENT = \"#009E73\"  # Okabe-Ito green for structural zone annotations\n\n# Code 128 B subset encoding (bar widths per character, 6 elements each)\nCODE128_B = {\n    \" \": [2, 1, 2, 2, 2, 2],\n    \"!\": [2, 2, 2, 1, 2, 2],\n    '\"': [2, 2, 2, 2, 2, 1],\n    \"#\": [1, 2, 1, 2, 2, 3],\n    \"$\": [1, 2, 1, 3, 2, 2],\n    \"%\": [1, 3, 1, 2, 2, 2],\n    \"&\": [1, 2, 2, 2, 1, 3],\n    \"'\": [1, 2, 2, 3, 1, 2],\n    \"(\": [1, 3, 2, 2, 1, 2],\n    \")\": [2, 2, 1, 2, 1, 3],\n    \"*\": [2, 2, 1, 3, 1, 2],\n    \"+\": [2, 3, 1, 2, 1, 2],\n    \",\": [1, 1, 2, 2, 3, 2],\n    \"-\": [1, 2, 2, 1, 3, 2],\n    \".\": [1, 2, 2, 2, 3, 1],\n    \"/\": [1, 1, 3, 2, 2, 2],\n    \"0\": [1, 2, 3, 1, 2, 2],\n    \"1\": [1, 2, 3, 2, 2, 1],\n    \"2\": [2, 2, 3, 2, 1, 1],\n    \"3\": [2, 2, 1, 1, 3, 2],\n    \"4\": [2, 2, 1, 2, 3, 1],\n    \"5\": [2, 1, 3, 2, 1, 2],\n    \"6\": [2, 2, 3, 1, 1, 2],\n    \"7\": [3, 1, 2, 1, 3, 1],\n    \"8\": [3, 1, 1, 2, 2, 2],\n    \"9\": [3, 2, 1, 1, 2, 2],\n    \":\": [3, 2, 1, 2, 2, 1],\n    \";\": [3, 1, 2, 2, 1, 2],\n    \"<\": [3, 2, 2, 1, 1, 2],\n    \"=\": [3, 2, 2, 2, 1, 1],\n    \">\": [2, 1, 2, 1, 2, 3],\n    \"?\": [2, 1, 2, 3, 2, 1],\n    \"@\": [2, 3, 2, 1, 2, 1],\n    \"A\": [1, 1, 1, 3, 2, 3],\n    \"B\": [1, 3, 1, 1, 2, 3],\n    \"C\": [1, 3, 1, 3, 2, 1],\n    \"D\": [1, 1, 2, 3, 1, 3],\n    \"E\": [1, 3, 2, 1, 1, 3],\n    \"F\": [1, 3, 2, 3, 1, 1],\n    \"G\": [2, 1, 1, 3, 1, 3],\n    \"H\": [2, 3, 1, 1, 1, 3],\n    \"I\": [2, 3, 1, 3, 1, 1],\n    \"J\": [1, 1, 2, 1, 3, 3],\n    \"K\": [1, 1, 2, 3, 3, 1],\n    \"L\": [1, 3, 2, 1, 3, 1],\n    \"M\": [1, 1, 3, 1, 2, 3],\n    \"N\": [1, 1, 3, 3, 2, 1],\n    \"O\": [1, 3, 3, 1, 2, 1],\n    \"P\": [3, 1, 3, 1, 2, 1],\n    \"Q\": [2, 1, 1, 3, 3, 1],\n    \"R\": [2, 3, 1, 1, 3, 1],\n    \"S\": [2, 1, 3, 1, 1, 3],\n    \"T\": [2, 1, 3, 3, 1, 1],\n    \"U\": [2, 1, 3, 1, 3, 1],\n    \"V\": [3, 1, 1, 1, 2, 3],\n    \"W\": [3, 1, 1, 3, 2, 1],\n    \"X\": [3, 3, 1, 1, 2, 1],\n    \"Y\": [3, 1, 2, 1, 1, 3],\n    \"Z\": [3, 1, 2, 3, 1, 1],\n    \"[\": [3, 3, 2, 1, 1, 1],\n    \"\\\\\": [3, 1, 4, 1, 1, 1],\n    \"]\": [2, 2, 1, 4, 1, 1],\n    \"^\": [4, 3, 1, 1, 1, 1],\n    \"_\": [1, 1, 1, 2, 2, 4],\n    \"`\": [1, 1, 1, 4, 2, 2],\n    \"a\": [1, 2, 1, 1, 2, 4],\n    \"b\": [1, 2, 1, 4, 2, 1],\n    \"c\": [1, 4, 1, 1, 2, 2],\n    \"d\": [1, 4, 1, 2, 2, 1],\n    \"e\": [1, 1, 2, 2, 1, 4],\n    \"f\": [1, 1, 2, 4, 1, 2],\n    \"g\": [1, 2, 2, 1, 1, 4],\n    \"h\": [1, 2, 2, 4, 1, 1],\n    \"i\": [1, 4, 2, 1, 1, 2],\n    \"j\": [1, 4, 2, 2, 1, 1],\n    \"k\": [2, 4, 1, 2, 1, 1],\n    \"l\": [2, 2, 1, 1, 1, 4],\n    \"m\": [4, 1, 3, 1, 1, 1],\n    \"n\": [2, 4, 1, 1, 1, 2],\n    \"o\": [1, 3, 4, 1, 1, 1],\n    \"p\": [1, 1, 1, 2, 4, 2],\n    \"q\": [1, 2, 1, 1, 4, 2],\n    \"r\": [1, 2, 1, 2, 4, 1],\n    \"s\": [1, 1, 4, 2, 1, 2],\n    \"t\": [1, 2, 4, 1, 1, 2],\n    \"u\": [1, 2, 4, 2, 1, 1],\n    \"v\": [4, 1, 1, 2, 1, 2],\n    \"w\": [4, 2, 1, 1, 1, 2],\n    \"x\": [4, 2, 1, 2, 1, 1],\n    \"y\": [2, 1, 2, 1, 4, 1],\n    \"z\": [2, 1, 4, 1, 2, 1],\n    \"{\": [4, 1, 2, 1, 2, 1],\n    \"|\": [1, 1, 1, 1, 4, 3],\n    \"}\": [1, 1, 1, 3, 4, 1],\n    \"~\": [1, 3, 1, 1, 4, 1],\n}\n\n# Code 128 value lookup for checksum calculation\nCODE128_VALUES = {\n    \" \": 0,\n    \"!\": 1,\n    '\"': 2,\n    \"#\": 3,\n    \"$\": 4,\n    \"%\": 5,\n    \"&\": 6,\n    \"'\": 7,\n    \"(\": 8,\n    \")\": 9,\n    \"*\": 10,\n    \"+\": 11,\n    \",\": 12,\n    \"-\": 13,\n    \".\": 14,\n    \"/\": 15,\n    \"0\": 16,\n    \"1\": 17,\n    \"2\": 18,\n    \"3\": 19,\n    \"4\": 20,\n    \"5\": 21,\n    \"6\": 22,\n    \"7\": 23,\n    \"8\": 24,\n    \"9\": 25,\n    \":\": 26,\n    \";\": 27,\n    \"<\": 28,\n    \"=\": 29,\n    \">\": 30,\n    \"?\": 31,\n    \"@\": 32,\n    \"A\": 33,\n    \"B\": 34,\n    \"C\": 35,\n    \"D\": 36,\n    \"E\": 37,\n    \"F\": 38,\n    \"G\": 39,\n    \"H\": 40,\n    \"I\": 41,\n    \"J\": 42,\n    \"K\": 43,\n    \"L\": 44,\n    \"M\": 45,\n    \"N\": 46,\n    \"O\": 47,\n    \"P\": 48,\n    \"Q\": 49,\n    \"R\": 50,\n    \"S\": 51,\n    \"T\": 52,\n    \"U\": 53,\n    \"V\": 54,\n    \"W\": 55,\n    \"X\": 56,\n    \"Y\": 57,\n    \"Z\": 58,\n    \"[\": 59,\n    \"\\\\\": 60,\n    \"]\": 61,\n    \"^\": 62,\n    \"_\": 63,\n    \"`\": 64,\n    \"a\": 65,\n    \"b\": 66,\n    \"c\": 67,\n    \"d\": 68,\n    \"e\": 69,\n    \"f\": 70,\n    \"g\": 71,\n    \"h\": 72,\n    \"i\": 73,\n    \"j\": 74,\n    \"k\": 75,\n    \"l\": 76,\n    \"m\": 77,\n    \"n\": 78,\n    \"o\": 79,\n    \"p\": 80,\n    \"q\": 81,\n    \"r\": 82,\n    \"s\": 83,\n    \"t\": 84,\n    \"u\": 85,\n    \"v\": 86,\n    \"w\": 87,\n    \"x\": 88,\n    \"y\": 89,\n    \"z\": 90,\n    \"{\": 91,\n    \"|\": 92,\n    \"}\": 93,\n    \"~\": 94,\n}\n\n# Special patterns\nSTART_B = [2, 1, 1, 2, 1, 4]  # Start Code B (value 104)\nSTOP = [2, 3, 3, 1, 1, 1, 2]  # Stop pattern\n\n# Checksum character patterns (values 0–102)\nCHECKSUM_PATTERNS = [\n    [2, 1, 2, 2, 2, 2],\n    [2, 2, 2, 1, 2, 2],\n    [2, 2, 2, 2, 2, 1],\n    [1, 2, 1, 2, 2, 3],\n    [1, 2, 1, 3, 2, 2],\n    [1, 3, 1, 2, 2, 2],\n    [1, 2, 2, 2, 1, 3],\n    [1, 2, 2, 3, 1, 2],\n    [1, 3, 2, 2, 1, 2],\n    [2, 2, 1, 2, 1, 3],\n    [2, 2, 1, 3, 1, 2],\n    [2, 3, 1, 2, 1, 2],\n    [1, 1, 2, 2, 3, 2],\n    [1, 2, 2, 1, 3, 2],\n    [1, 2, 2, 2, 3, 1],\n    [1, 1, 3, 2, 2, 2],\n    [1, 2, 3, 1, 2, 2],\n    [1, 2, 3, 2, 2, 1],\n    [2, 2, 3, 2, 1, 1],\n    [2, 2, 1, 1, 3, 2],\n    [2, 2, 1, 2, 3, 1],\n    [2, 1, 3, 2, 1, 2],\n    [2, 2, 3, 1, 1, 2],\n    [3, 1, 2, 1, 3, 1],\n    [3, 1, 1, 2, 2, 2],\n    [3, 2, 1, 1, 2, 2],\n    [3, 2, 1, 2, 2, 1],\n    [3, 1, 2, 2, 1, 2],\n    [3, 2, 2, 1, 1, 2],\n    [3, 2, 2, 2, 1, 1],\n    [2, 1, 2, 1, 2, 3],\n    [2, 1, 2, 3, 2, 1],\n    [2, 3, 2, 1, 2, 1],\n    [1, 1, 1, 3, 2, 3],\n    [1, 3, 1, 1, 2, 3],\n    [1, 3, 1, 3, 2, 1],\n    [1, 1, 2, 3, 1, 3],\n    [1, 3, 2, 1, 1, 3],\n    [1, 3, 2, 3, 1, 1],\n    [2, 1, 1, 3, 1, 3],\n    [2, 3, 1, 1, 1, 3],\n    [2, 3, 1, 3, 1, 1],\n    [1, 1, 2, 1, 3, 3],\n    [1, 1, 2, 3, 3, 1],\n    [1, 3, 2, 1, 3, 1],\n    [1, 1, 3, 1, 2, 3],\n    [1, 1, 3, 3, 2, 1],\n    [1, 3, 3, 1, 2, 1],\n    [3, 1, 3, 1, 2, 1],\n    [2, 1, 1, 3, 3, 1],\n    [2, 3, 1, 1, 3, 1],\n    [2, 1, 3, 1, 1, 3],\n    [2, 1, 3, 3, 1, 1],\n    [2, 1, 3, 1, 3, 1],\n    [3, 1, 1, 1, 2, 3],\n    [3, 1, 1, 3, 2, 1],\n    [3, 3, 1, 1, 2, 1],\n    [3, 1, 2, 1, 1, 3],\n    [3, 1, 2, 3, 1, 1],\n    [3, 3, 2, 1, 1, 1],\n    [3, 1, 4, 1, 1, 1],\n    [2, 2, 1, 4, 1, 1],\n    [4, 3, 1, 1, 1, 1],\n    [1, 1, 1, 2, 2, 4],\n    [1, 1, 1, 4, 2, 2],\n    [1, 2, 1, 1, 2, 4],\n    [1, 2, 1, 4, 2, 1],\n    [1, 4, 1, 1, 2, 2],\n    [1, 4, 1, 2, 2, 1],\n    [1, 1, 2, 2, 1, 4],\n    [1, 1, 2, 4, 1, 2],\n    [1, 2, 2, 1, 1, 4],\n    [1, 2, 2, 4, 1, 1],\n    [1, 4, 2, 1, 1, 2],\n    [1, 4, 2, 2, 1, 1],\n    [2, 4, 1, 2, 1, 1],\n    [2, 2, 1, 1, 1, 4],\n    [4, 1, 3, 1, 1, 1],\n    [2, 4, 1, 1, 1, 2],\n    [1, 3, 4, 1, 1, 1],\n    [1, 1, 1, 2, 4, 2],\n    [1, 2, 1, 1, 4, 2],\n    [1, 2, 1, 2, 4, 1],\n    [1, 1, 4, 2, 1, 2],\n    [1, 2, 4, 1, 1, 2],\n    [1, 2, 4, 2, 1, 1],\n    [4, 1, 1, 2, 1, 2],\n    [4, 2, 1, 1, 1, 2],\n    [4, 2, 1, 2, 1, 1],\n    [2, 1, 2, 1, 4, 1],\n    [2, 1, 4, 1, 2, 1],\n    [4, 1, 2, 1, 2, 1],\n    [1, 1, 1, 1, 4, 3],\n    [1, 1, 1, 3, 4, 1],\n    [1, 3, 1, 1, 4, 1],\n    [1, 1, 4, 1, 1, 3],\n    [1, 1, 4, 3, 1, 1],\n    [4, 1, 1, 1, 1, 3],\n    [4, 1, 1, 3, 1, 1],\n    [1, 1, 3, 1, 4, 1],\n    [1, 1, 4, 1, 3, 1],\n    [3, 1, 1, 1, 4, 1],\n    [4, 1, 1, 1, 3, 1],\n    [2, 1, 1, 4, 1, 2],\n    [2, 1, 1, 2, 1, 4],\n    [2, 1, 1, 2, 3, 2],\n]\n\n# Barcode content: shipping label example\ncontent = \"SHIP-2024-ABC123\"\n\n# Calculate checksum (needed before zone tracking for the annotation label)\nchecksum = 104  # Start B value\nfor i, char in enumerate(content):\n    checksum += CODE128_VALUES[char] * (i + 1)\nchecksum = checksum % 103\n\n# Build bar positions with zone tracking for structural annotations\nquiet_zone = 10  # standard 10-module quiet zones on each side\nx_pos = quiet_zone\nis_bar = True\nbar_lefts, bar_rights, bar_descs = [], [], []\nzones = []  # list of (label, x_start, x_end) for zone bracket annotations\n\n\ndef _append_bars(widths, desc):\n    \"\"\"Consume a pattern of widths, appending bars (not spaces) to the lists.\"\"\"\n    global x_pos, is_bar\n    for w in widths:\n        if is_bar:\n            bar_lefts.append(x_pos)\n            bar_rights.append(x_pos + w)\n            bar_descs.append(desc)\n        x_pos += w\n        is_bar = not is_bar\n\n\n# Zone: Start Code B\nzs = x_pos\n_append_bars(START_B, \"Start Code B\")\nzones.append((\"Start B\", zs, x_pos))\n\n# Zone: Data payload — each character tracked individually for HoverTool\nzs = x_pos\nfor i, char in enumerate(content):\n    _append_bars(CODE128_B[char], f\"'{char}'  (position {i + 1})\")\nzones.append((\"Data Payload\", zs, x_pos))\n\n# Zone: Check digit\nzs = x_pos\n_append_bars(CHECKSUM_PATTERNS[checksum], f\"Check Digit  (value {checksum})\")\nzones.append((\"Check Digit\", zs, x_pos))\n\n# Zone: Stop\nzs = x_pos\n_append_bars(STOP, \"Stop Pattern\")\nzones.append((\"Stop\", zs, x_pos))\n\ntotal_modules = x_pos + quiet_zone\n\n# Layout y-coordinates — expanded canvas to accommodate zone annotations above bars\nBAR_TOP = 570\nBAR_BOTTOM = 80\nBRACKET_Y = 608  # horizontal bracket line above bars\nZONE_TEXT_Y = 638  # zone label text above bracket\nSUBTITLE_Y = 690  # informational subtitle above zone labels\nWHITE_TOP = 735  # top of white barcode background rect\nWHITE_BOTTOM = 20\n\n# Create figure — 3200×1800 canonical landscape canvas\nW, H = 3200, 1800\np = figure(\n    width=W,\n    height=H,\n    title=\"barcode-code128 · python · bokeh · anyplot.ai\",\n    x_range=(0, total_modules),\n    y_range=(0, 760),\n    toolbar_location=None,\n    min_border_bottom=80,\n    min_border_left=60,\n    min_border_top=110,\n    min_border_right=60,\n)\n\n# Typography\np.title.text_font_size = \"50pt\"\np.title.align = \"center\"\np.title.text_color = INK\n\n# Theme-adaptive canvas background\np.background_fill_color = PAGE_BG\np.border_fill_color = PAGE_BG\np.outline_line_color = None\n\n# No axes or grid — barcode is a self-contained graphic\np.xaxis.visible = False\np.yaxis.visible = False\np.xgrid.visible = False\np.ygrid.visible = False\n\n# White label background — spec requires high-contrast black bars on white\np.quad(left=0, right=total_modules, top=WHITE_TOP, bottom=WHITE_BOTTOM, fill_color=\"#FFFFFF\", line_color=None)\n\n# Barcode bars — ColumnDataSource enables HoverTool interactivity\nsource = ColumnDataSource(\n    data={\n        \"left\": bar_lefts,\n        \"right\": bar_rights,\n        \"top\": [BAR_TOP] * len(bar_lefts),\n        \"bottom\": [BAR_BOTTOM] * len(bar_lefts),\n        \"desc\": bar_descs,\n    }\n)\nbars = p.quad(\n    left=\"left\", right=\"right\", top=\"top\", bottom=\"bottom\", fill_color=\"#000000\", line_color=None, source=source\n)\n\n# HoverTool — Bokeh's distinctive interactive feature: reveals encoded element on hover\nhover = HoverTool(renderers=[bars], tooltips=[(\"Element\", \"@desc\")])\np.add_tools(hover)\n\n# Zone bracket annotations — educates the viewer about barcode structure\nBRACKET_LW = 4\nfor zone_label, zx_start, zx_end in zones:\n    zmid = (zx_start + zx_end) / 2\n    # Horizontal bracket line spanning the zone\n    p.segment(x0=[zx_start], y0=[BRACKET_Y], x1=[zx_end], y1=[BRACKET_Y], line_color=ACCENT, line_width=BRACKET_LW)\n    # Vertical ticks down from bracket to bar top\n    p.segment(\n        x0=[zx_start, zx_end],\n        y0=[BAR_TOP, BAR_TOP],\n        x1=[zx_start, zx_end],\n        y1=[BRACKET_Y, BRACKET_Y],\n        line_color=ACCENT,\n        line_width=BRACKET_LW,\n    )\n    # Zone label text centered above bracket\n    p.add_layout(\n        Label(\n            x=zmid,\n            y=ZONE_TEXT_Y,\n            text=zone_label,\n            text_align=\"center\",\n            text_baseline=\"bottom\",\n            text_font_size=\"22pt\",\n            text_color=ACCENT,\n        )\n    )\n\n# Informational subtitle — context for the viewer (DE-01)\np.add_layout(\n    Label(\n        x=total_modules / 2,\n        y=SUBTITLE_Y,\n        text=f\"Code 128 Subset B  ·  {len(content)} characters  ·  checksum: mod 103  ·  quiet zones: 10 modules\",\n        text_align=\"center\",\n        text_baseline=\"bottom\",\n        text_font_size=\"22pt\",\n        text_color=INK_SOFT,\n    )\n)\n\n# Human-readable text below barcode\np.add_layout(\n    Label(\n        x=total_modules / 2,\n        y=48,\n        text=content,\n        text_font_size=\"34pt\",\n        text_align=\"center\",\n        text_baseline=\"middle\",\n        text_color=\"#000000\",\n        text_font=\"monospace\",\n    )\n)\n\n# Save interactive HTML with inline resources (no CDN dependency for offline rendering)\nhtml_path = Path(f\"plot-{THEME}.html\").resolve()\nhtml_path.write_text(file_html(p, INLINE))\n\n# Screenshot with headless Chrome via Selenium + CDP for exact dimensions\nopts = Options()\nfor arg in (\n    \"--headless=new\",\n    \"--no-sandbox\",\n    \"--disable-dev-shm-usage\",\n    \"--disable-gpu\",\n    f\"--window-size={W},{H}\",\n    \"--hide-scrollbars\",\n):\n    opts.add_argument(arg)\ndriver = webdriver.Chrome(options=opts)\ndriver.set_window_size(W, H)\ndriver.get(f\"file://{html_path}\")\ntime.sleep(3)\n\n# CDP captureScreenshot handles browser-chrome offset and captures at exact W×H\nresult = driver.execute_cdp_cmd(\n    \"Page.captureScreenshot\",\n    {\"format\": \"png\", \"captureBeyondViewport\": True, \"clip\": {\"x\": 0, \"y\": 0, \"width\": W, \"height\": H, \"scale\": 1.0}},\n)\nPath(f\"plot-{THEME}.png\").write_bytes(base64.b64decode(result[\"data\"]))\ndriver.quit()\n"}