var/cache/dev/twig/ce/ce33f1a336b501ccf515e493a104daa7fd455b12fbf3de30504bd569466a894b.php line 40

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\SandboxExtension;
  6. use Twig\Markup;
  7. use Twig\Sandbox\SecurityError;
  8. use Twig\Sandbox\SecurityNotAllowedTagError;
  9. use Twig\Sandbox\SecurityNotAllowedFilterError;
  10. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  11. use Twig\Source;
  12. use Twig\Template;
  13. /* Product/detail.twig */
  14. class __TwigTemplate_da5ad31feda8695d41b76c2e300641cf69fccce492d7fb053b687f2a0b3adb3c extends \Eccube\Twig\Template
  15. {
  16.     private $source;
  17.     private $macros = [];
  18.     public function __construct(Environment $env)
  19.     {
  20.         parent::__construct($env);
  21.         $this->source $this->getSourceContext();
  22.         $this->blocks = [
  23.             'stylesheet' => [$this'block_stylesheet'],
  24.             'javascript' => [$this'block_javascript'],
  25.             'main' => [$this'block_main'],
  26.         ];
  27.     }
  28.     protected function doGetParent(array $context)
  29.     {
  30.         // line 11
  31.         return "default_frame.twig";
  32.     }
  33.     protected function doDisplay(array $context, array $blocks = [])
  34.     {
  35.         $macros $this->macros;
  36.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  37.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/detail.twig"));
  38.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  39.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/detail.twig"));
  40.         // line 13
  41.         $context["body_class"] = "product_page";
  42.         // line 11
  43.         $this->parent $this->loadTemplate("default_frame.twig""Product/detail.twig"11);
  44.         $this->parent->display($contextarray_merge($this->blocks$blocks));
  45.         
  46.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  47.         
  48.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  49.     }
  50.     // line 15
  51.     public function block_stylesheet($context, array $blocks = [])
  52.     {
  53.         $macros $this->macros;
  54.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  55.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  56.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  57.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  58.         // line 16
  59.         echo "    <style>
  60.         .slick-slider {
  61.             margin-bottom: 10px;
  62. \t\t\tmargin-top: -20px;
  63.         }
  64.         .slick-dots {
  65.             position: absolute;
  66.             bottom: -45px;
  67.             display: block;
  68.             width: 100%;
  69.             padding: 0;
  70.             list-style: none;
  71.             text-align: center;
  72.         }
  73.         .slick-dots li {
  74.             position: relative;
  75.             display: inline-block;
  76.             width: 20px;
  77.             height: 20px;
  78.             margin: 0 5px;
  79.             padding: 0;
  80.             cursor: pointer;
  81.         }
  82.         .slick-dots li button {
  83.             font-size: 0;
  84.             line-height: 0;
  85.             display: block;
  86.             width: 20px;
  87.             height: 20px;
  88.             padding: 5px;
  89.             cursor: pointer;
  90.             color: transparent;
  91.             border: 0;
  92.             outline: none;
  93.             background: transparent;
  94.         }
  95.         .slick-dots li button:hover,
  96.         .slick-dots li button:focus {
  97.             outline: none;
  98.         }
  99.         .slick-dots li button:hover:before,
  100.         .slick-dots li button:focus:before {
  101.             opacity: 1;
  102.         }
  103.         .slick-dots li button:before {
  104.             content: \" \";
  105.             line-height: 20px;
  106.             position: absolute;
  107.             top: 0;
  108.             left: 0;
  109.             width: 12px;
  110.             height: 12px;
  111.             text-align: center;
  112.             opacity: .25;
  113.             background-color: black;
  114.             border-radius: 50%;
  115.         }
  116.         .slick-dots li.slick-active button:before {
  117.             opacity: .75;
  118.             background-color: black;
  119.         }
  120.         .slick-dots li button.thumbnail img {
  121.             width: 0;
  122.             height: 0;
  123.         }
  124.     </style>
  125.     <link rel=\"stylesheet\" href=\"/html/user_data/js/style.css\">
  126.     <link rel=\"stylesheet\" href=\"/html/plugins/icheck-bootstrap/icheck-bootstrap.min.css\">
  127.     <style>
  128.         /* Show zoom cursor on product images to hint click-to-expand */
  129.         .item_visual .slide-item a { display: block; cursor: zoom-in; }
  130.     </style>
  131.     <style>
  132.         /* ============================================
  133.            商品詳細グリッド: 画像50% / 内容50%(均等)
  134.         ============================================ */
  135.         @media (min-width: 768px) {
  136.             body.product_page .ec-grid2 {
  137.                 display: flex;
  138.                 align-items: flex-start;
  139.             }
  140.             body.product_page .ec-grid2 .ec-grid2__cell {
  141.                 width: 50%;
  142.                 flex: 0 0 50%;
  143.                 min-width: 0;
  144.             }
  145.             body.product_page .ec-grid2 .ec-grid2__cell2 {
  146.                 width: 50%;
  147.                 flex: 0 0 50%;
  148.                 min-width: 0;
  149.             }
  150.         }
  151.         /* ============================================
  152.            商品説明欄内のHTMLが画面幅を突き抜けないように
  153.         ============================================ */
  154.         body.product_page .ec-productRole__description {
  155.             min-width: 0;
  156.             overflow-wrap: break-word;
  157.             word-break: break-word;
  158.         }
  159.         body.product_page .ec-productRole__description img,
  160.         body.product_page .ec-productRole__description table,
  161.         body.product_page .ec-productRole__description iframe,
  162.         body.product_page .ec-productRole__description video {
  163.             max-width: 100% !important;
  164.             height: auto;
  165.         }
  166.         body.product_page .ec-productRole__description table {
  167.             display: block;
  168.             overflow-x: auto;
  169.             -webkit-overflow-scrolling: touch;
  170.         }
  171.         /* ============================================
  172.            スマホ用 見積金額 下部固定バー
  173.         ============================================ */
  174.         #sp-mitsumori-bar {
  175.             display: none;
  176.         }
  177.         
  178.         /* ============================================
  179.            商品タイプ選択 共通スタイル
  180.         ============================================ */
  181.         /* セクションラベル */
  182.         .rp-section-label {
  183.             font-size: 14px;
  184.             font-weight: bold;
  185.             color: #333;
  186.             margin-bottom: 10px;
  187.         }
  188.         .rp-section-label span {
  189.             font-weight: normal;
  190.             color: #c00;
  191.         }
  192.         /* ---- 1. 画像付きカード ---- */
  193.         .rp-card-group {
  194.             display: flex;
  195.             flex-wrap: wrap;
  196.             gap: 8px;
  197.             margin-bottom: 4px;
  198.         }
  199.         .rp-card {
  200.             position: relative;
  201.             cursor: pointer;
  202.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  203.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  204.             width: 110px;
  205.             border: 2px solid #ddd;
  206.             border-radius: 10px;
  207.             overflow: hidden;
  208.             transition: border-color 0.2s, box-shadow 0.2s;
  209.             background: #fff;
  210.             text-decoration: none;
  211.             color: #333;
  212.             display: block;
  213.         }
  214.         /* Gate :hover behind real hover-capable pointers. On iOS Safari a
  215.            :hover rule that changes appearance makes the first tap apply the
  216.            hover state and suppresses the click, so the option chip needed a
  217.            second tap to fire its onclick (is-selected + price update). */
  218.         @media (hover: hover) and (pointer: fine) {
  219.             .rp-card:hover {
  220.                 border-color: #999;
  221.                 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  222.             }
  223.         }
  224.         .rp-card.is-selected {
  225.             border-color: #1a6fcf;
  226.             box-shadow: 0 2px 10px rgba(26,111,207,0.25);
  227.         }
  228.         /* visually-hidden instead of display:none. A label wrapping a
  229.            display:none radio fires its tap unreliably on iOS Safari (first tap
  230.            often ignored -> \"2回タッチ\"). Keeping the input in the layout but
  231.            invisible makes the first tap register. */
  232.         .rp-card input[type=\"radio\"] {
  233.             position: absolute; opacity: 0; width: 1px; height: 1px;
  234.             margin: 0; pointer-events: none;
  235.         }
  236.         .rp-card__image {
  237.             width: 100%;
  238.             aspect-ratio: 1 / 1;
  239.             object-fit: cover;
  240.             display: block;
  241.             background: #f5f5f5;
  242.         }
  243.         .rp-card__placeholder {
  244.             width: 100%;
  245.             aspect-ratio: 1 / 1;
  246.             background: #f0f0f0;
  247.             display: flex;
  248.             align-items: center;
  249.             justify-content: center;
  250.             color: #bbb;
  251.             font-size: 24px;
  252.         }
  253.         .rp-card__name {
  254.             display: block;
  255.             padding: 5px 5px;
  256.             font-size: 11px;
  257.             color: #333;
  258.             text-align: center;
  259.             line-height: 1.4;
  260.             word-break: break-all;
  261.         }
  262.         .rp-card.is-selected .rp-card__name { color: #1a6fcf; font-weight: bold; }
  263.         .rp-card.is-selected::after {
  264.             content: \"✓\";
  265.             position: absolute;
  266.             top: 3px; right: 6px;
  267.             color: #1a6fcf;
  268.             font-size: 13px;
  269.             font-weight: bold;
  270.         }
  271.         /* ---- 2. ボタン式ラジオ(画像なし・8個以内)---- */
  272.         .rp-btn-group {
  273.             display: flex;
  274.             flex-wrap: wrap;
  275.             gap: 8px;
  276.             margin-bottom: 4px;
  277.             max-width: 100%;
  278.             min-width: 0;
  279.         }
  280.         .rp-btn {
  281.             cursor: pointer;
  282.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  283.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  284.             padding: 8px 14px;
  285.             border: 2px solid #ddd;
  286.             border-radius: 10px;
  287.             font-size: 13px;
  288.             color: #333;
  289.             background: #fff;
  290.             transition: border-color 0.2s, background 0.2s;
  291.             white-space: normal;
  292.             max-width: 100%;
  293.             overflow-wrap: anywhere;
  294.             text-decoration: none;
  295.         }
  296.         @media (hover: hover) and (pointer: fine) {
  297.             .rp-btn:hover { border-color: #999; }
  298.         }
  299.         .rp-btn.is-selected {
  300.             border-color: #1a6fcf;
  301.             color: #1a6fcf;
  302.             font-weight: bold;
  303.             background: #f0f6ff;
  304.         }
  305.         .rp-btn input[type=\"radio\"] {
  306.             position: absolute; opacity: 0; width: 1px; height: 1px;
  307.             margin: 0; pointer-events: none;
  308.         }
  309.         /* iOS Safari \"2回タッチ\" fix for the type-selection link chips.
  310.            The global theme stylesheet ships an ungated `a:hover{color:#296292}`
  311.            (paired with `a{color:#337ab7;text-decoration:underline}`). Because
  312.            .rp-btn / .rp-card are real <a> links, iOS Safari applies that hover
  313.            colour on the FIRST tap — the chip text turns blue (#296292, the
  314.            reported \"字だけ青くなる\") — and treats the tap as a hover, swallowing
  315.            the navigation so a 2nd tap was needed. The local .rp-*:hover rules
  316.            are already gated behind (hover:hover), but this inherited global
  317.            rule was not. Pin the hover/active colour to the base/selected colour
  318.            so tapping produces no visual change and the first tap navigates
  319.            immediately. Higher specificity (0,2,0 / 0,3,0) overrides a:hover. */
  320.         .rp-btn:hover,
  321.         .rp-btn:active { color: #333; text-decoration: none; }
  322.         .rp-btn.is-selected:hover,
  323.         .rp-btn.is-selected:active { color: #1a6fcf; text-decoration: none; }
  324.         .rp-card:hover,
  325.         .rp-card:active { color: #333; text-decoration: none; }
  326.         .rp-card:hover .rp-card__name,
  327.         .rp-card:active .rp-card__name { color: #333; }
  328.         .rp-card.is-selected:hover .rp-card__name,
  329.         .rp-card.is-selected:active .rp-card__name { color: #1a6fcf; }
  330.         /* ---- 選択肢が多い場合: 縦3段に収めて横スクロール(顧客要望「3列くらいで横スクロール」)---- */
  331.         /* grid-auto-flow:column + 3行固定 → 選択肢が縦に最大3段、超過分は右へ伸び横スクロールで閲覧 */
  332.         .rp-btn-group.is-scroll,
  333.         .opt-btn-group.is-scroll {
  334.             display: grid;
  335.             grid-auto-flow: column;
  336.             grid-template-rows: repeat(3, auto);
  337.             grid-auto-columns: max-content;
  338.             justify-content: start;
  339.             align-items: start;
  340.             gap: 8px;
  341.             overflow-x: auto;
  342.             overflow-y: hidden;
  343.             -webkit-overflow-scrolling: touch;
  344.             scrollbar-width: thin;
  345.             /* 上下に余白を確保して、行の枠線が overflow クリップ/スクロールバーに
  346.                切り取られないようにする(「文字列が長いと下枠が消える」対策)。 */
  347.             padding: 2px 0 12px;
  348.         }
  349.         /* is-scroll(横スクロール)内では選択肢を折り返さず単一行に固定する。
  350.            折り返すと行高が不揃いになり overflow-y:hidden で下枠が切れるため、
  351.            長い選択肢は折り返さず横スクロールで見せる(本来の設計意図)。 */
  352.         .rp-btn-group.is-scroll .rp-btn,
  353.         .rp-btn-group.is-scroll .opt-btn,
  354.         .opt-btn-group.is-scroll .rp-btn,
  355.         .opt-btn-group.is-scroll .opt-btn {
  356.             white-space: nowrap;
  357.             word-break: normal;
  358.             overflow-wrap: normal;
  359.         }
  360.         .rp-btn-group.is-scroll::-webkit-scrollbar,
  361.         .opt-btn-group.is-scroll::-webkit-scrollbar {
  362.             height: 6px;
  363.         }
  364.         .rp-btn-group.is-scroll::-webkit-scrollbar-thumb,
  365.         .opt-btn-group.is-scroll::-webkit-scrollbar-thumb {
  366.             background: #c0c0c0;
  367.             border-radius: 3px;
  368.         }
  369.         /* ---- 3. プルダウン(画像なし・9個以上)---- */
  370.         .rp-select-wrap {
  371.             margin-bottom: 4px;
  372.         }
  373.         .rp-select {
  374.             width: 100%;
  375.             max-width: 420px;
  376.             padding: 8px 12px;
  377.             border: 2px solid #ddd;
  378.             border-radius: 10px;
  379.             font-size: 13px;
  380.             color: #333;
  381.             background: #fff;
  382.             appearance: none;
  383.             background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E\");
  384.             background-repeat: no-repeat;
  385.             background-position: right 12px center;
  386.             cursor: pointer;
  387.         }
  388.         .rp-select:focus {
  389.             outline: none;
  390.             border-color: #1a6fcf;
  391.         }
  392.         /* ---- オプション選択ボタン(枠線ラジオ)---- */
  393.         .opt-btn-group {
  394.             display: flex;
  395.             flex-wrap: wrap;
  396.             gap: 8px;
  397.             padding: 6px 0;
  398.             max-width: 100%;
  399.             min-width: 0;
  400.         }
  401.         .opt-btn {
  402.             cursor: pointer;
  403.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  404.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  405.             padding: 7px 14px;
  406.             border: 2px solid #ddd;
  407.             border-radius: 10px;
  408.             font-size: 13px;
  409.             color: #333;
  410.             background: #fff;
  411.             transition: border-color 0.2s, background 0.2s;
  412.             white-space: normal;
  413.             max-width: 100%;
  414.             overflow-wrap: anywhere;
  415.             text-decoration: none;
  416.         }
  417.         @media (hover: hover) and (pointer: fine) {
  418.             .opt-btn:hover { border-color: #999; }
  419.         }
  420.         .opt-btn.is-selected {
  421.             border-color: #1a6fcf;
  422.             color: #1a6fcf;
  423.             font-weight: bold;
  424.             background: #f0f6ff;
  425.         }
  426.         .opt-btn input[type=\"radio\"] {
  427.             position: absolute; opacity: 0; width: 1px; height: 1px;
  428.             margin: 0; pointer-events: none;
  429.         }
  430.         /* opt-btn with color swatch image. The label still works as a
  431.            radio target — clicking the image checks the input. The text
  432.            label stays under the image so users can still read the name. */
  433.         .opt-btn--with-image {
  434.             padding: 4px 6px 6px;
  435.             white-space: normal;
  436.             text-align: center;
  437.             display: inline-flex;
  438.             flex-direction: column;
  439.             align-items: center;
  440.             min-width: 96px;
  441.             max-width: 140px;
  442.         }
  443.         .opt-btn--with-image .opt-btn__img {
  444.             display: block;
  445.             width: 88px;
  446.             height: 66px;
  447.             object-fit: cover;
  448.             border-radius: 6px;
  449.             margin-bottom: 4px;
  450.             background: #f5f5f5;
  451.         }
  452.         .opt-btn--with-image .opt-btn__name {
  453.             display: block;
  454.             font-size: 11px;
  455.             line-height: 1.3;
  456.             color: inherit;
  457.         }
  458.         .opt-btn--with-image.is-selected .opt-btn__img {
  459.             outline: 2px solid #1a6fcf;
  460.             outline-offset: 1px;
  461.         }
  462.         /* sale_type=2 (内窓) 補助金対象ガラスの強調表示.
  463.            補助金が出る性能区分 (真空断熱 / Low-E複層 等) のガラス選択肢に
  464.            緑枠 + 「補助金対象」バッジを付け、選択前から判別できるようにする。 */
  465.         .opt-btn--subsidy {
  466.             border-color: #2e7d32;
  467.         }
  468.         .opt-btn--subsidy.is-selected {
  469.             border-color: #1a6fcf;
  470.         }
  471.         .opt-btn__subsidy-badge {
  472.             display: inline-block;
  473.             margin-left: 6px;
  474.             padding: 1px 6px;
  475.             border-radius: 6px;
  476.             background: #2e7d32;
  477.             color: #fff;
  478.             font-size: 11px;
  479.             font-weight: bold;
  480.             white-space: nowrap;
  481.         }
  482.         /* ============================================
  483.            施工エリア案内
  484.         ============================================ */
  485.         .ec-areaNotice {
  486.             margin: 16px 0;
  487.             padding: 16px 20px;
  488.             background: #f8f9fa;
  489.             border-left: 4px solid #1a6fcf;
  490.             border-radius: 0 8px 8px 0;
  491.         }
  492.         .ec-areaNotice__inner {
  493.             display: flex;
  494.             align-items: flex-start;
  495.             gap: 12px;
  496.         }
  497.         .ec-areaNotice__icon {
  498.             font-size: 22px;
  499.             line-height: 1;
  500.             flex-shrink: 0;
  501.             margin-top: 2px;
  502.         }
  503.         .ec-areaNotice__body {
  504.             flex: 1;
  505.         }
  506.         .ec-areaNotice__title {
  507.             font-size: 13px;
  508.             font-weight: bold;
  509.             color: #1a6fcf;
  510.             margin: 0 0 6px;
  511.         }
  512.         .ec-areaNotice__text {
  513.             font-size: 13px;
  514.             color: #444;
  515.             line-height: 1.7;
  516.             margin: 0;
  517.         }
  518.         .ec-areaNotice__text strong {
  519.             color: #222;
  520.         }
  521.         .ec-areaNotice__link {
  522.             display: inline-block;
  523.             margin-top: 8px;
  524.             font-size: 12px;
  525.             color: #1a6fcf;
  526.             text-decoration: underline;
  527.         }
  528.         .ec-areaNotice__link:hover {
  529.             color: #0d4fa0;
  530.         }
  531.         /* ============================================
  532.            SNSシェア + ブランド名 タイトル行
  533.         ============================================ */
  534.         .ec-productRole__titleRow {
  535.             display: flex;
  536.             align-items: center;
  537.             justify-content: space-between;
  538.             gap: 8px;
  539.             margin-bottom: 4px;
  540.         }
  541.         .ec-productRole__titleRow .ec-headingTitle {
  542.             margin: 0;
  543.             flex: 1;
  544.             font-size: 18px;
  545.         }
  546.         .ec-share-inline {
  547.             display: flex;
  548.             align-items: center;
  549.             gap: 8px;
  550.             flex-shrink: 0;
  551.         }
  552.         @media (max-width: 767px) {
  553.             /* maker_area の float を解除して独立表示 */
  554.             #maker_area {
  555.                 float: none !important;
  556.                 width: auto !important;
  557.                 height: auto !important;
  558.                 display: block;
  559.                 margin-bottom: 4px;
  560.             }
  561.             /* タイトル行: 商品名が全幅を占有しSNSは右寄せ下段 */
  562.             .ec-productRole__titleRow {
  563.                 flex-wrap: wrap;
  564.                 clear: both;
  565.             }
  566.             .ec-productRole__titleRow .ec-headingTitle {
  567.                 flex: 1 1 100%;
  568.                 font-size: 16px;
  569.             }
  570.             .ec-share-inline {
  571.                 flex: 0 0 auto;
  572.                 margin-left: auto;
  573.             }
  574.         }
  575.         .ec-share-inline a {
  576.             display: flex;
  577.             align-items: center;
  578.             justify-content: center;
  579.             width: 32px;
  580.             height: 32px;
  581.             border-radius: 50%;
  582.             font-size: 15px;
  583.             color: #fff;
  584.             text-decoration: none;
  585.             transition: opacity 0.2s;
  586.         }
  587.         .ec-share-inline a:hover { opacity: 0.8; }
  588.         .ec-share-inline .share-twitter  { background: #000; }
  589.         .ec-share-inline .share-facebook { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); }
  590.         .ec-share-inline .share-line     { background: #06c755; }
  591.         /* description_detail下のシェアブロックはPC/スマホ共通で非表示(タイトル行に移動) */
  592.         .ec-productRole__share { display: none; }
  593.         /* ============================================
  594.            PC用: 現在のお見積り額カード強調
  595.         ============================================ */
  596.         @media (min-width: 768px) {
  597.             .mitsumori-card-pc {
  598.                 border: 2px solid #1a6fcf !important;
  599.                 border-radius: 10px !important;
  600.                 box-shadow: 0 4px 16px rgba(26,111,207,0.18) !important;
  601.                 margin-top: 20px;
  602.                 overflow: hidden;
  603.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  604.             }
  605.             .mitsumori-card-pc .card-header {
  606.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  607.                 color: #fff !important;
  608.                 padding: 14px 16px !important;
  609.                 border-bottom: none !important;
  610.             }
  611.             .mitsumori-card-pc .card-title {
  612.                 color: #fff !important;
  613.                 font-size: 15px !important;
  614.                 font-weight: bold !important;
  615.                 margin: 0 !important;
  616.             }
  617.             .mitsumori-card-pc #mitsumori_message {
  618.                 font-size: 22px !important;
  619.                 font-weight: bold !important;
  620.                 color: #fff !important;
  621.             }
  622.             .mitsumori-card-pc .btn-tool {
  623.                 color: #fff !important;
  624.             }
  625.             /* 合計行を大きく強調 */
  626.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  627.                 font-size: 16px !important;
  628.                 font-weight: bold !important;
  629.                 color: #c00 !important;
  630.                 background: #fff8f8 !important;
  631.                 padding: 12px 16px !important;
  632.             }
  633.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  634.                 font-size: 20px !important;
  635.                 font-weight: bold !important;
  636.                 color: #c00 !important;
  637.             }
  638.             /* card-body(明細リスト)を白背景に */
  639.             .mitsumori-card-pc .card-body {
  640.                 background: #fff !important;
  641.             }
  642.             .mitsumori-card-pc .card-footer {
  643.                 background: #f8faff !important;
  644.                 border-top: 1px solid #dce8fb !important;
  645.                 padding: 12px 16px !important;
  646.             }
  647.         }
  648.         @media (max-width: 767px) {
  649.             /* スマホでは現在のお見積り額カードの強調スタイルをすべてリセット */
  650.             .mitsumori-card-pc {
  651.                 border: none !important;
  652.                 border-radius: 0 !important;
  653.                 box-shadow: none !important;
  654.                 margin-top: 0 !important;
  655.                 overflow: visible !important;
  656.                 background: none !important;
  657.                 /* sticky-top(position:sticky / z-index:1020) を解除。
  658.                    そのままだと最下部で #sp-mitsumori-bar(z-index:1000) の上に
  659.                    重なり、合計バーと文字が被るため通常フローへ戻す。 */
  660.                 position: static !important;
  661.                 z-index: auto !important;
  662.             }
  663.             .mitsumori-card-pc .card-header {
  664.                 background: none !important;
  665.                 color: inherit !important;
  666.                 padding: inherit !important;
  667.                 border-bottom: inherit !important;
  668.             }
  669.             .mitsumori-card-pc .card-title { color: inherit !important; }
  670.             .mitsumori-card-pc #mitsumori_message { font-size: inherit !important; color: inherit !important; }
  671.             .mitsumori-card-pc .btn-tool { color: inherit !important; }
  672.             /* 折りたたみトグルボタン */
  673.             .btn-mitsumori-toggle {
  674.                 background: none !important;
  675.                 border: 1px solid #aaa !important;
  676.                 border-radius: 4px !important;
  677.                 padding: 2px 8px !important;
  678.                 font-size: 12px !important;
  679.                 color: #333 !important;
  680.                 line-height: 1.4 !important;
  681.             }
  682.             .btn-mitsumori-toggle .toggle-icon {
  683.                 display: inline-block;
  684.                 transition: transform 0.2s;
  685.             }
  686.             /* 展開状態: ▼→▲ */
  687.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon::before {
  688.                 content: \"▲ 閉じる\";
  689.             }
  690.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon {
  691.                 display: none;
  692.             }
  693.             .card:not(.collapsed-card) .btn-mitsumori-toggle::after {
  694.                 content: \"▲ 閉じる\";
  695.                 font-size: 12px;
  696.             }
  697.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  698.                 font-size: inherit !important;
  699.                 color: inherit !important;
  700.                 background: none !important;
  701.                 padding: inherit !important;
  702.             }
  703.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  704.                 font-size: inherit !important;
  705.                 color: inherit !important;
  706.             }
  707.             .mitsumori-card-pc .card-footer {
  708.                 background: none !important;
  709.                 border-top: inherit !important;
  710.                 padding: inherit !important;
  711.             }
  712.             /* 横スクロール禁止 */
  713.             body, html {
  714.                 overflow-x: hidden;
  715.                 max-width: 100vw;
  716.             }
  717.             /* ボタンの折り返しを許可(nowrapが原因で横スクロール発生するため) */
  718.             .opt-btn,
  719.             .rp-btn {
  720.                 white-space: normal;
  721.                 word-break: break-all;
  722.             }
  723.             /* エリア案内: スマホでコンパクト */
  724.             .ec-areaNotice {
  725.                 margin: 8px 0;
  726.                 padding: 8px 10px;
  727.                 border-left-width: 3px;
  728.                 cursor: pointer;
  729.             }
  730.             .ec-areaNotice__inner {
  731.                 flex-direction: row;
  732.                 gap: 8px;
  733.                 align-items: flex-start;
  734.             }
  735.             .ec-areaNotice__icon { font-size: 15px; }
  736.             /* タイトル行: 展開トグル */
  737.             .ec-areaNotice__title {
  738.                 font-size: 11px;
  739.                 margin-bottom: 3px;
  740.                 display: flex;
  741.                 justify-content: space-between;
  742.                 align-items: center;
  743.             }
  744.             .ec-areaNotice__title::after {
  745.                 content: \"▼\";
  746.                 font-size: 9px;
  747.                 color: #888;
  748.                 margin-left: 6px;
  749.                 transition: transform 0.2s;
  750.             }
  751.             .ec-areaNotice.is-open .ec-areaNotice__title::after {
  752.                 transform: rotate(180deg);
  753.             }
  754.             /* 折りたたみ対象: 閉じた状態では非表示 */
  755.             .ec-areaNotice__detail {
  756.                 display: none;
  757.             }
  758.             .ec-areaNotice.is-open .ec-areaNotice__detail {
  759.                 display: block;
  760.             }
  761.             .ec-areaNotice__text { font-size: 11px; line-height: 1.5; }
  762.             .ec-areaNotice__text br { display: none; }
  763.             .ec-areaNotice__link { font-size: 11px; margin-top: 3px; }
  764.             .rp-card { width: calc(33.333% - 6px); min-width: 80px; }
  765.             
  766.             #sp-mitsumori-bar {
  767.                 display: flex;
  768.                 position: fixed;
  769.                 bottom: 0;
  770.                 left: 0;
  771.                 right: 0;
  772.                 z-index: 1000;
  773.                 background: #fff;
  774.                 border-top: 2px solid #e0e0e0;
  775.                 box-shadow: 0 -2px 8px rgba(0,0,0,0.12);
  776.                 align-items: center;
  777.                 padding: 8px 10px calc(8px + env(safe-area-inset-bottom)) 10px;
  778.                 gap: 8px;
  779.             }
  780.             #sp-mitsumori-bar .sp-bar__label {
  781.                 font-size: 11px;
  782.                 color: #666;
  783.                 white-space: nowrap;
  784.             }
  785.             /* 価格ラッパ: 合計金額は最重要のため常に全桁表示する(縮小・省略しない)。
  786.                幅が足りない場合は下のボタン側を縮める(flex 配分でボタンが先に縮む)。 */
  787.             #sp-mitsumori-bar .sp-bar__pricewrap {
  788.                 flex: 0 0 auto;
  789.                 min-width: 0;
  790.             }
  791.             #sp-mitsumori-bar .sp-bar__price {
  792.                 font-size: 18px;
  793.                 font-weight: bold;
  794.                 color: #c00;
  795.                 white-space: nowrap;
  796.             }
  797.             #sp-mitsumori-bar .sp-bar__btn {
  798.                 font-size: 12px;
  799.                 padding: 8px 12px;
  800.                 background: #333;
  801.                 color: #fff;
  802.                 border: none;
  803.                 border-radius: 6px;
  804.                 white-space: nowrap;
  805.                 cursor: pointer;
  806.                 position: relative;
  807.                 display: inline-flex;
  808.                 align-items: center;
  809.                 gap: 6px;
  810.                 flex: 1 1 auto;
  811.                 min-width: 0;
  812.                 justify-content: center;
  813.             }
  814.             #sp-mitsumori-bar .sp-bar__btn i {
  815.                 font-size: 14px;
  816.                 flex: 0 0 auto;
  817.             }
  818.             /* 幅が足りないときはボタンの文字を省略し、価格と数字を守る。 */
  819.             #sp-mitsumori-bar .sp-bar__btn-label {
  820.                 overflow: hidden;
  821.                 text-overflow: ellipsis;
  822.                 white-space: nowrap;
  823.             }
  824.             #sp-mitsumori-bar .sp-bar__cart-badge {
  825.                 position: absolute;
  826.                 top: -6px;
  827.                 right: -6px;
  828.                 background: #c00;
  829.                 color: #fff;
  830.                 border-radius: 50%;
  831.                 min-width: 16px;
  832.                 height: 16px;
  833.                 font-size: 10px;
  834.                 line-height: 16px;
  835.                 padding: 0 4px;
  836.                 font-weight: bold;
  837.             }
  838.             #sp-mitsumori-bar .sp-bar__home-btn {
  839.                 display: inline-flex;
  840.                 align-items: center;
  841.                 justify-content: center;
  842.                 width: 36px;
  843.                 height: 36px;
  844.                 flex: 0 0 auto;
  845.                 border: 1px solid #ccc;
  846.                 border-radius: 6px;
  847.                 background: #fff;
  848.                 color: #333;
  849.                 text-decoration: none;
  850.                 cursor: pointer;
  851.             }
  852.             #sp-mitsumori-bar .sp-bar__home-btn i {
  853.                 font-size: 16px;
  854.             }
  855.             #sp-mitsumori-bar .sp-bar__home-btn:hover {
  856.                 background: #f0f0f0;
  857.             }
  858.             /* 下部バーの高さ分ページ下部にpaddingを追加 (iOS safe-area 込み) */
  859.             body {
  860.                 padding-bottom: calc(80px + env(safe-area-inset-bottom));
  861.             }
  862.         }
  863.         /* ============================================
  864.            カート追加モーダル: 縦並び中央配置
  865.         ============================================ */
  866.         .add-cart-modal__wrap {
  867.             text-align: center;
  868.         }
  869.         .add-cart-modal__header {
  870.             font-size: 16px;
  871.             margin: 20px 0 24px;
  872.             text-align: center;
  873.         }
  874.         .add-cart-modal__actions {
  875.             display: flex;
  876.             flex-direction: column;
  877.             align-items: center;
  878.             gap: 16px;
  879.             padding: 0 20px 20px;
  880.         }
  881.         .add-cart-modal__primary {
  882.             display: inline-block;
  883.             width: 80%;
  884.             max-width: 320px;
  885.             padding: 14px 20px;
  886.             font-size: 15px;
  887.             font-weight: bold;
  888.             text-align: center;
  889.             background: #d9534f;
  890.             color: #fff !important;
  891.             border-radius: 6px;
  892.             text-decoration: none;
  893.             cursor: pointer;
  894.         }
  895.         .add-cart-modal__primary:hover {
  896.             background: #c9302c;
  897.             color: #fff !important;
  898.             text-decoration: none;
  899.         }
  900.         .add-cart-modal__secondary {
  901.             display: inline-block;
  902.             padding: 6px 14px;
  903.             font-size: 12px;
  904.             color: #666;
  905.             border: 1px solid #ccc;
  906.             border-radius: 4px;
  907.             background: #fff;
  908.             cursor: pointer;
  909.         }
  910.         .add-cart-modal__secondary:hover {
  911.             background: #f0f0f0;
  912.             color: #333;
  913.         }
  914.         @media (max-width: 767px) {
  915.             .add-cart-modal__actions {
  916.                 gap: 20px;
  917.             }
  918.         }
  919.     </style>
  920. ";
  921.         
  922.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  923.         
  924.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  925.     }
  926.     // line 908
  927.     public function block_javascript($context, array $blocks = [])
  928.     {
  929.         $macros $this->macros;
  930.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  931.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  932.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  933.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  934.         // line 909
  935.         echo "
  936.     <script>
  937.         eccube.classCategories = ";
  938.         // line 911
  939.         echo $this->extensions['Eccube\Twig\Extension\EccubeExtension']->getClassCategoriesAsJson((isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'911$this->source); })()));
  940.         echo ";
  941.         // 規格2に選択肢を割り当てる。
  942.         function fnSetClassCategories(form, classcat_id2_selected) {
  943.             var \$form = \$(form);
  944.             var product_id = \$form.find('input[name=product_id]').val();
  945.             var \$sele1 = \$form.find('select[name=classcategory_id1]');
  946.             var \$sele2 = \$form.find('select[name=classcategory_id2]');
  947.             eccube.setClassCategories(\$form, product_id, \$sele1, \$sele2, classcat_id2_selected);
  948.         }
  949.         ";
  950.         // line 922
  951.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse922)) {
  952.             // line 923
  953.             echo "        fnSetClassCategories(
  954.             \$('#form1'), ";
  955.             // line 924
  956.             echo json_encode(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'924$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse924), "vars", [], "any"falsefalsefalse924), "value", [], "any"falsefalsefalse924));
  957.             echo "
  958.         );
  959.         ";
  960.         } elseif (twig_get_attribute($this->env$this->source,         // line 926
  961. ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse926)) {
  962.             // line 927
  963.             echo "        eccube.checkStock(\$('#form1'), ";
  964.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'927$this->source); })()), "id", [], "any"falsefalsefalse927), "html"nulltrue);
  965.             echo ", ";
  966.             echo json_encode(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'927$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse927), "vars", [], "any"falsefalsefalse927), "value", [], "any"falsefalsefalse927));
  967.             echo ", null);
  968.         ";
  969.         }
  970.         // line 929
  971.         echo "    </script>
  972.     <script>
  973.         \$(function() {
  974.             // bfcache無効化
  975.             \$(window).bind('pageshow', function(event) {
  976.                 if (event.originalEvent.persisted) {
  977.                     location.reload(true);
  978.                 }
  979.             });
  980.             // Core Web Vital の Cumulative Layout Shift(CLS)対策のため
  981.             // img タグに width, height が付与されている.
  982.             // 630px 未満の画面サイズでは縦横比が壊れるための対策
  983.             // see https://github.com/EC-CUBE/ec-cube/pull/5023
  984.             \$('.ec-grid2__cell').hide();
  985.             var removeSize = function () {
  986.                 \$('.slide-item').height('');
  987.                 \$('.slide-item img')
  988.                     .removeAttr('width')
  989.                     .removeAttr('height')
  990.                     .removeAttr('style');
  991.             };
  992.             var slickInitial = function(slick) {
  993.                 \$('.ec-grid2__cell').fadeIn(1500);
  994.                 var baseHeight = \$(slick.target).height();
  995.                 var baseWidth = \$(slick.target).width();
  996.                 var rate = baseWidth / baseHeight;
  997. \t\t\t\tif(baseHeight * rate < 400){
  998. \t                \$('.slide-item').height(baseHeight * rate); // 余白を削除する
  999. \t\t\t\t}else{
  1000. \t                \$('.slide-item').height(400); // 余白を削除する
  1001. \t\t\t\t}
  1002.                 // transform を使用することでCLSの影響を受けないようにする
  1003.                 \$('.slide-item img')
  1004.                     .css(
  1005.                         {
  1006.                             'transform-origin': 'top left',
  1007.                             'transform': 'scaleY(' + rate + ')',
  1008.                             'transition': 'transform .1s'
  1009.                         }
  1010.                     );
  1011.                 // 正しいサイズに近くなったら属性を解除する
  1012.                 setTimeout(removeSize, 500);
  1013.             };
  1014.             \$('.item_visual').on('init', slickInitial);
  1015.             // リサイズ時は CLS の影響を受けないため属性を解除する
  1016.             \$(window).resize(removeSize);
  1017.             \$('.item_visual').slick({
  1018.                 dots: false,
  1019.                 arrows: true,
  1020.                 responsive: [{
  1021.                     breakpoint: 768,
  1022.                     settings: {
  1023.                         dots: true,
  1024.                 \t\tarrows: false
  1025.                     }
  1026.                 }]
  1027.             });
  1028.             \$('.slideThumb').on('click', function() {
  1029.                 var index = \$(this).attr('data-index');
  1030.                 \$('.item_visual').slick('slickGoTo', index, false);
  1031.             })
  1032.         });
  1033.     </script>
  1034.     <script>
  1035.         \$(function() {
  1036.             \$('.add-cart').on('click', function(event) {
  1037.                 ";
  1038.         // line 999
  1039.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse999)) {
  1040.             // line 1000
  1041.             echo "                // 規格1フォームの必須チェック
  1042.                 if (\$('#classcategory_id1').val() == '__unselected' || \$('#classcategory_id1').val() == '') {
  1043.                     \$('#classcategory_id1')[0].setCustomValidity('";
  1044.             // line 1002
  1045.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("項目が選択されていません"), "html"nulltrue);
  1046.             echo "');
  1047.                     return true;
  1048.                 } else {
  1049.                     \$('#classcategory_id1')[0].setCustomValidity('');
  1050.                 }
  1051.                 ";
  1052.         }
  1053.         // line 1008
  1054.         echo "
  1055.                 ";
  1056.         // line 1009
  1057.         if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse1009)) {
  1058.             // line 1010
  1059.             echo "                // 規格2フォームの必須チェック
  1060.                 if (\$('#classcategory_id2').val() == '__unselected' || \$('#classcategory_id2').val() == '') {
  1061.                     \$('#classcategory_id2')[0].setCustomValidity('";
  1062.             // line 1012
  1063.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("項目が選択されていません"), "html"nulltrue);
  1064.             echo "');
  1065.                     return true;
  1066.                 } else {
  1067.                     \$('#classcategory_id2')[0].setCustomValidity('');
  1068.                 }
  1069.                 ";
  1070.         }
  1071.         // line 1018
  1072.         echo "
  1073.                 // タイプ2: カート送信直前に set_count を quantity に同期
  1074.                 if(\$('#set_count').length){
  1075.                     var _sc = parseInt(\$('#set_count').val()) || 1;
  1076.                     \$('#quantity').val(_sc);
  1077.                     \$('input[name=\"quantity\"]').val(_sc);
  1078.                 }
  1079.                 // 個数フォームのチェック
  1080.                 if (\$('#quantity').val() < 1) {
  1081.                     \$('#quantity')[0].setCustomValidity('";
  1082.         // line 1028
  1083.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("1以上で入力してください。"), "html"nulltrue);
  1084.         echo "');
  1085.                     return true;
  1086.                 } else {
  1087.                     \$('#quantity')[0].setCustomValidity('');
  1088.                 }
  1089.                 event.preventDefault();
  1090.                 \$form = \$('#form1');
  1091.                 \$.ajax({
  1092.                     url: \$form.attr('action'),
  1093.                     type: \$form.attr('method'),
  1094.                     data: \$form.serialize(),
  1095.                     dataType: 'json',
  1096.                     beforeSend: function(xhr, settings) {
  1097.                         // Buttonを無効にする
  1098.                         \$('.add-cart').prop('disabled', true);
  1099.                     }
  1100.                 }).done(function(data) {
  1101.                     // レスポンス内のメッセージをalertで表示
  1102.                     \$.each(data.messages, function() {
  1103.                         \$('#ec-modal-header').text(this);
  1104.                     });
  1105.                     \$('.ec-modal').show()
  1106.                     // カートブロックを更新する
  1107.                     \$.ajax({
  1108.                         url: \"";
  1109.         // line 1055
  1110.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("block_cart");
  1111.         echo "\",
  1112.                         type: 'GET',
  1113.                         dataType: 'html'
  1114.                     }).done(function(html) {
  1115.                         \$('.ec-headerRole__cart').html(html);
  1116.                     });
  1117.                 }).fail(function(data) {
  1118.                     alert('";
  1119.         // line 1062
  1120.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートへの追加に失敗しました。"), "html"nulltrue);
  1121.         echo "');
  1122.                 }).always(function(data) {
  1123.                     // Buttonを有効にする
  1124.                     \$('.add-cart').prop('disabled', false);
  1125.                 });
  1126.             });
  1127.         });
  1128.         \$('.ec-modal-wrap').on('click', function(e) {
  1129.             // モーダル内の処理は外側にバブリングさせない
  1130.             e.stopPropagation();
  1131.         });
  1132.         \$('.ec-modal-overlay, .ec-modal, .ec-modal-close, .ec-inlineBtn--cancel').on('click', function() {
  1133.             \$('.ec-modal').hide()
  1134.         });
  1135. \t\tvar pw = \"";
  1136.         // line 1079
  1137.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1079$this->source); })())) {
  1138.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1079$this->source); })()), "pw", [], "any"falsefalsefalse1079), "html"nulltrue);
  1139.         }
  1140.         echo "\";
  1141. \t\tvar pd = \"";
  1142.         // line 1080
  1143.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1080$this->source); })())) {
  1144.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1080$this->source); })()), "pd", [], "any"falsefalsefalse1080), "html"nulltrue);
  1145.         }
  1146.         echo "\";
  1147. \t\tvar ph = \"";
  1148.         // line 1081
  1149.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1081$this->source); })())) {
  1150.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1081$this->source); })()), "ph", [], "any"falsefalsefalse1081), "html"nulltrue);
  1151.         }
  1152.         echo "\";
  1153. \t\tvar pm = \"";
  1154.         // line 1082
  1155.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1082$this->source); })())) {
  1156.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1082$this->source); })()), "pm", [], "any"falsefalsefalse1082), "html"nulltrue);
  1157.         }
  1158.         echo "\";
  1159. \t\tvar pc = \"";
  1160.         // line 1083
  1161.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1083$this->source); })())) {
  1162.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1083$this->source); })()), "pc", [], "any"falsefalsefalse1083), "html"nulltrue);
  1163.         }
  1164.         echo "\";
  1165. \t\t// option1 / option2: カテゴリ別 option 軸 (um: タイプ=subtype, fe: ct_up 等)
  1166. \t\tvar option1 = \"";
  1167.         // line 1085
  1168.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1085$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse1085))) {
  1169.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1085$this->source); })()), "option1", [], "any"falsefalsefalse1085), "html"nulltrue);
  1170.         }
  1171.         echo "\";
  1172. \t\tvar option2 = \"";
  1173.         // line 1086
  1174.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1086$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse1086))) {
  1175.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1086$this->source); })()), "option2", [], "any"falsefalsefalse1086), "html"nulltrue);
  1176.         }
  1177.         echo "\";
  1178. \t\tvar op0 = \"";
  1179.         // line 1087
  1180.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1087$this->source); })())) {
  1181.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1087$this->source); })()), "op", [], "any"falsefalsefalse1087), 0, [], "array"falsefalsefalse1087), "html"nulltrue);
  1182.         }
  1183.         echo "\";
  1184. \t\tvar op1 = \"";
  1185.         // line 1088
  1186.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1088$this->source); })())) {
  1187.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1088$this->source); })()), "op", [], "any"falsefalsefalse1088), 1, [], "array"falsefalsefalse1088), "html"nulltrue);
  1188.         }
  1189.         echo "\";
  1190. \t\tvar op2 = \"";
  1191.         // line 1089
  1192.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1089$this->source); })())) {
  1193.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1089$this->source); })()), "op", [], "any"falsefalsefalse1089), 2, [], "array"falsefalsefalse1089), "html"nulltrue);
  1194.         }
  1195.         echo "\";
  1196. \t\tvar op3 = \"";
  1197.         // line 1090
  1198.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1090$this->source); })())) {
  1199.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1090$this->source); })()), "op", [], "any"falsefalsefalse1090), 3, [], "array"falsefalsefalse1090), "html"nulltrue);
  1200.         }
  1201.         echo "\";
  1202. \t\tvar op4 = \"";
  1203.         // line 1091
  1204.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1091$this->source); })())) {
  1205.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1091$this->source); })()), "op", [], "any"falsefalsefalse1091), 4, [], "array"falsefalsefalse1091), "html"nulltrue);
  1206.         }
  1207.         echo "\";
  1208. \t\tvar op5 = \"";
  1209.         // line 1092
  1210.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1092$this->source); })())) {
  1211.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1092$this->source); })()), "op", [], "any"falsefalsefalse1092), 5, [], "array"falsefalsefalse1092), "html"nulltrue);
  1212.         }
  1213.         echo "\";
  1214. \t\tvar op6 = \"";
  1215.         // line 1093
  1216.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1093$this->source); })())) {
  1217.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1093$this->source); })()), "op", [], "any"falsefalsefalse1093), 6, [], "array"falsefalsefalse1093), "html"nulltrue);
  1218.         }
  1219.         echo "\";
  1220. \t\tvar op7 = \"";
  1221.         // line 1094
  1222.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1094$this->source); })())) {
  1223.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1094$this->source); })()), "op", [], "any"falsefalsefalse1094), 7, [], "array"falsefalsefalse1094), "html"nulltrue);
  1224.         }
  1225.         echo "\";
  1226. \t\tvar op8 = \"";
  1227.         // line 1095
  1228.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1095$this->source); })())) {
  1229.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1095$this->source); })()), "op", [], "any"falsefalsefalse1095), 8, [], "array"falsefalsefalse1095), "html"nulltrue);
  1230.         }
  1231.         echo "\";
  1232. \t\tvar op9 = \"";
  1233.         // line 1096
  1234.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1096$this->source); })())) {
  1235.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1096$this->source); })()), "op", [], "any"falsefalsefalse1096), 9, [], "array"falsefalsefalse1096), "html"nulltrue);
  1236.         }
  1237.         echo "\";
  1238. \t\tvar op10 = \"";
  1239.         // line 1097
  1240.         if ((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1097$this->source); })())) {
  1241.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'1097$this->source); })()), "op", [], "any"falsefalsefalse1097), 10, [], "array"falsefalsefalse1097), "html"nulltrue);
  1242.         }
  1243.         echo "\";
  1244. \t\tconst formatter = new Intl.NumberFormat('ja-JP');
  1245. \t\t// ============================================================
  1246. \t\t//  free_area 1 エントリのスキーマ(11 キー固定)
  1247. \t\t// ============================================================
  1248. \t\t//   w           : 幅 (string, 例 \"239.9cm\" / tf は \"1m\")
  1249. \t\t//   d           : 奥行
  1250. \t\t//   h           : 高さ (tf はロール長 \"10m\")
  1251. \t\t//   m           : 素材
  1252. \t\t//   c           : カラー
  1253. \t\t//   price       : 販売価格 (税抜、amount=1 ベース)
  1254. \t\t//   unit_price  : 商品 per-unit 増分 (税抜、AMOUNT_CATEGORIES のみ)
  1255. \t\t//   maker_price : メーカー価格 (税抜)
  1256. \t\t//   ct          : 基本工事費 (税抜、amount=1 ベース)
  1257. \t\t//   option1     : fe → ct_up / その他カテゴリ → category-specific
  1258. \t\t//   option2     : um → ct_up / その他カテゴリ → category-specific
  1259. \t\t//
  1260. \t\t//  ct4 (設置場所) / ct5 (撤去) / ct6 (残土) は option_area 側で扱う.
  1261. \t\t// ============================================================
  1262. \t\t// 施工オプション定義(option_area)— 各エントリ {name, comment, on, off, price}
  1263. \t\tvar op_data = ";
  1264.         // line 1120
  1265.         echo ((array_key_exists("op_json"$context)) ? (_twig_default_filter((isset($context["op_json"]) || array_key_exists("op_json"$context) ? $context["op_json"] : (function () { throw new RuntimeError('Variable "op_json" does not exist.'1120$this->source); })()), "[]")) : ("[]"));
  1266.         echo ";
  1267. \t\t// option_item_area:
  1268. \t\t//   tg 用 — block 別オプション差額表
  1269. \t\t//     { axis_labels: {F:'床材',front:'前面型',side1:'右側面型',side2:'左側面型'},
  1270. \t\t//       blocks: { 'W_label|D_label': { F:[{idx,label,diff},...], front:[...], side1:[...], side2:[...] }, ... } }
  1271. \t\t//   fe (sale_type=4) 用 — ブロックの種類×段数の差額表 (fe_block キー)
  1272. \t\t//     { fe_block: { depends_on_name: '...', depends_on_value: '...',
  1273. \t\t//                   title: '...', default_key: '...',
  1274. \t\t//                   choices: [{key,label,price}, ...] } }
  1275. \t\t// 該当しないカテゴリでは fe_block は null. axis_labels/blocks は空.
  1276. \t\tvar oi_data = ";
  1277.         // line 1131
  1278.         echo ((array_key_exists("oi_json"$context)) ? (_twig_default_filter((isset($context["oi_json"]) || array_key_exists("oi_json"$context) ? $context["oi_json"] : (function () { throw new RuntimeError('Variable "oi_json" does not exist.'1131$this->source); })()), "{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}")) : ("{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}"));
  1279.         echo ";
  1280. \t\t// 選択中の tg オプション差額 (axis -> selected choice_idx). ラジオ click で更新される.
  1281. \t\tvar oi_selected = { F: 1, front: 1, side1: 1, side2: 1 };
  1282. \t\t// 選択中の fe ブロック種類×段数 (key 文字列). 既定は oi_data.fe_block.default_key.
  1283. \t\tvar fe_block_selected = (oi_data && oi_data.fe_block && oi_data.fe_block.default_key) || '';
  1284. \t\t// sale_type ID(mtb_sale_type の id。本サイトでの意味は次の通り):
  1285. \t\t//   1 通常 / 2 補助金窓 / 3 物置 / 4 フェンス / 5 デッキ / 6 芝生 / 9 商品のみ
  1286. \t\tvar SALE_TYPE_ID = ";
  1287.         // line 1141
  1288.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'1141$this->source); })()), "SaleType", [], "any"falsefalsefalse1141), "id", [], "any"falsefalsefalse1141), "html"nulltrue);
  1289.         echo ";
  1290. \t\t";
  1291.         // line 1144
  1292.         echo "\t\t";
  1293.         $context["option1_label"] = "オプション1";
  1294.         // line 1145
  1295.         echo "\t\t";
  1296.         $context["option2_label"] = "オプション2";
  1297.         // line 1146
  1298.         echo "\t\t";
  1299.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1146$this->source); })()), "ProductCategories", [], "any"falsefalsefalse1146))) {
  1300.             // line 1147
  1301.             echo "\t\t\t";
  1302.             $context['_parent'] = $context;
  1303.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1147$this->source); })()), "ProductCategories", [], "any"falsefalsefalse1147));
  1304.             foreach ($context['_seq'] as $context["_key"] => $context["pcat"]) {
  1305.                 // line 1148
  1306.                 echo "\t\t\t\t";
  1307.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1148) == 31)) {
  1308.                     $context["option1_label"] = "サイズプリセット";
  1309.                     $context["option2_label"] = "駆動方式";
  1310.                 }
  1311.                 // line 1149
  1312.                 echo "\t\t\t\t";
  1313.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1149) == 43)) {
  1314.                     $context["option1_label"] = "ランマ";
  1315.                     $context["option2_label"] = "タイプ";
  1316.                 }
  1317.                 // line 1150
  1318.                 echo "\t\t\t\t";
  1319.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1150) == 15)) {
  1320.                     $context["option1_label"] = "棚タイプ";
  1321.                 }
  1322.                 // line 1151
  1323.                 echo "\t\t\t\t";
  1324.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse1151) == 17)) {
  1325.                     $context["option1_label"] = "窓タイプ";
  1326.                 }
  1327.                 // line 1152
  1328.                 echo "\t\t\t";
  1329.             }
  1330.             $_parent $context['_parent'];
  1331.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pcat'], $context['_parent'], $context['loop']);
  1332.             $context array_intersect_key($context$_parent) + $_parent;
  1333.             // line 1153
  1334.             echo "\t\t";
  1335.         }
  1336.         // line 1154
  1337.         echo "
  1338. \t\t// 消費税率(pp.price/pp.ct/op_data.price は scraper が税抜で保存しているため、
  1339. \t\t// calcGoukei 出口で 1+TAX_RATE を掛けて税込 mitsumori_goukei にする)
  1340. \t\tvar TAX_RATE = 0.10;
  1341. \t\tfunction toIncTax(v) { return Math.round(v * (1 + TAX_RATE)); }
  1342. \t\t/**
  1343. \t\t * tg 用 block 別オプション差額の集計.
  1344. \t\t *   現選択 (W, D) から block key を作り、oi_data.blocks[blockKey] を取得.
  1345. \t\t *   各 axis (F/front/side1/side2) で oi_selected[axis] の choice の diff を合計.
  1346. \t\t * 戻り値: { total: 差額合計(税抜), items: [{name, label, diff}, ...] }
  1347. \t\t *   block が無い (tg 以外 / 該当 (W,D) が未取得) なら total=0.
  1348. \t\t */
  1349. \t\tfunction collectOptionItems(curW, curD) {
  1350. \t\t\tvar result = { total: 0, items: [] };
  1351. \t\t\tif (!oi_data || !oi_data.blocks) return result;
  1352. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  1353. \t\t\tvar block = oi_data.blocks[blockKey];
  1354. \t\t\tif (!block) return result;
  1355. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  1356. \t\t\tfor (var i = 0; i < axes.length; i++) {
  1357. \t\t\t\tvar axis = axes[i];
  1358. \t\t\t\tvar choices = block[axis];
  1359. \t\t\t\tif (!choices || !choices.length) continue;
  1360. \t\t\t\tvar idx = oi_selected[axis] || 1;
  1361. \t\t\t\tvar pick = null;
  1362. \t\t\t\tfor (var j = 0; j < choices.length; j++) {
  1363. \t\t\t\t\tif (parseInt(choices[j].idx) === parseInt(idx)) { pick = choices[j]; break; }
  1364. \t\t\t\t}
  1365. \t\t\t\tif (!pick) pick = choices[0];
  1366. \t\t\t\tvar diff = parseInt(pick.diff) || 0;
  1367. \t\t\t\tresult.total += diff;
  1368. \t\t\t\tresult.items.push({
  1369. \t\t\t\t\tname:  oi_data.axis_labels[axis] || axis,
  1370. \t\t\t\t\tlabel: pick.label,
  1371. \t\t\t\t\tdiff:  diff,
  1372. \t\t\t\t});
  1373. \t\t\t}
  1374. \t\t\treturn result;
  1375. \t\t}
  1376. \t\t/**
  1377. \t\t * tg ラジオ群を block 別に DOM へ描画する.
  1378. \t\t *   W/D が確定したら現 block の 4 軸 (F/front/side1/side2) ラジオを #tg-options 要素に出す.
  1379. \t\t *   block が空なら #tg-options を空にする.
  1380. \t\t */
  1381. \t\tfunction renderOptionItemRadios(curW, curD) {
  1382. \t\t\tvar \$box = \$('#tg-options');
  1383. \t\t\tif (!\$box.length) return;
  1384. \t\t\t\$box.empty();
  1385. \t\t\tif (!oi_data || !oi_data.blocks) return;
  1386. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  1387. \t\t\tvar block = oi_data.blocks[blockKey];
  1388. \t\t\tif (!block) return;
  1389. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  1390. \t\t\taxes.forEach(function(axis) {
  1391. \t\t\t\tvar choices = block[axis];
  1392. \t\t\t\tif (!choices || !choices.length) return;
  1393. \t\t\t\tvar axisLabel = (oi_data.axis_labels && oi_data.axis_labels[axis]) || axis;
  1394. \t\t\t\tvar \$section = \$('<div class=\"form-group tg-axis\"></div>');
  1395. \t\t\t\t\$section.append('<p class=\"rp-section-label\"><strong>' + axisLabel + '</strong>: <span class=\"tg-axis-selected\"></span></p>');
  1396. \t\t\t\tvar \$list = \$('<div class=\"tg-choice-list\"></div>');
  1397. \t\t\t\tchoices.forEach(function(ch, i) {
  1398. \t\t\t\t\tvar inputId = 'tg_' + axis + '_' + ch.idx;
  1399. \t\t\t\t\tvar name = 'tg_' + axis;
  1400. \t\t\t\t\tvar checked = (parseInt(ch.idx) === parseInt(oi_selected[axis] || 1)) ? ' checked' : '';
  1401. \t\t\t\t\tvar diffTxt = ch.diff > 0 ? '+' + formatter.format(ch.diff) + '円' : (ch.diff < 0 ? formatter.format(ch.diff) + '円' : '±0');
  1402. \t\t\t\t\t\$list.append(
  1403. \t\t\t\t\t\t'<label class=\"tg-choice\"><input type=\"radio\" name=\"' + name + '\" id=\"' + inputId + '\" value=\"' + ch.idx + '\" data-axis=\"' + axis + '\"' + checked + '> ' +
  1404. \t\t\t\t\t\tch.label + '<span class=\"tg-diff\">(' + diffTxt + ')</span></label>'
  1405. \t\t\t\t\t);
  1406. \t\t\t\t});
  1407. \t\t\t\t\$section.append(\$list);
  1408. \t\t\t\t\$box.append(\$section);
  1409. \t\t\t});
  1410. \t\t\t// ラジオ click で oi_selected を更新 → 再計算
  1411. \t\t\t\$box.off('change.tg').on('change.tg', 'input[type=\"radio\"][data-axis]', function() {
  1412. \t\t\t\tvar axis = \$(this).data('axis');
  1413. \t\t\t\toi_selected[axis] = parseInt(\$(this).val()) || 1;
  1414. \t\t\t\tmitsumori_simulation('refresh', '');
  1415. \t\t\t});
  1416. \t\t\tupdateOptionItemSelectedLabels();
  1417. \t\t}
  1418. \t\tfunction updateOptionItemSelectedLabels() {
  1419. \t\t\t\$('#tg-options .tg-axis').each(function() {
  1420. \t\t\t\tvar \$sel = \$(this).find('input[type=\"radio\"]:checked');
  1421. \t\t\t\tif (!\$sel.length) return;
  1422. \t\t\t\tvar label = \$sel.parent().contents().filter(function() { return this.nodeType === 3; }).text().trim();
  1423. \t\t\t\t\$(this).find('.tg-axis-selected').text(label);
  1424. \t\t\t});
  1425. \t\t}
  1426. \t\t// =========================================================
  1427. \t\t// fe (sale_type=4) ブロック種類×段数 サブ UI
  1428. \t\t// =========================================================
  1429. \t\t/**
  1430. \t\t * fe_block の親オプション (= op_data 内の「ご希望のフェンス設置方法」 entry)
  1431. \t\t * を name でルックアップし、その index を返す. 見つからなければ -1.
  1432. \t\t *   fe_block.depends_on_name が設定されていればそれで照合.
  1433. \t\t *   未設定なら 'ご希望のフェンス設置方法' を含む name にフォールバック.
  1434. \t\t */
  1435. \t\tfunction findFeBlockParentOpIndex() {
  1436. \t\t\tif (!oi_data || !oi_data.fe_block) return -1;
  1437. \t\t\tvar needle = oi_data.fe_block.depends_on_name || 'ご希望のフェンス設置方法';
  1438. \t\t\tfor (var i = 0; i < op_data.length; i++) {
  1439. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  1440. \t\t\t\tif (op_data[i].name.indexOf(needle) >= 0) return i;
  1441. \t\t\t}
  1442. \t\t\treturn -1;
  1443. \t\t}
  1444. \t\t/**
  1445. \t\t * fe_block の現在の選択値の price (税抜) と choice 内容を集計.
  1446. \t\t *   親オプション (= 'ご希望のフェンス設置方法') が depends_on_value を選んでいる
  1447. \t\t *   ときだけ加算する. それ以外 (既存ブロック側 / 親未選択) は price=0.
  1448. \t\t * 戻り値: { price: 0|N, choice: {key,label,price}|null, active: bool }
  1449. \t\t */
  1450. \t\tfunction collectFeBlock() {
  1451. \t\t\tvar result = { price: 0, choice: null, active: false };
  1452. \t\t\tif (SALE_TYPE_ID !== 4) return result;
  1453. \t\t\tif (!oi_data || !oi_data.fe_block) return result;
  1454. \t\t\tif (!oi_data.fe_block.choices || !oi_data.fe_block.choices.length) return result;
  1455. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1456. \t\t\tif (parentIdx < 0) return result;
  1457. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1458. \t\t\tvar parentSel = ops[parentIdx];
  1459. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  1460. \t\t\tif (parentSel !== triggerValue) return result;  // 親が新規ブロック積み以外なら無加算
  1461. \t\t\tresult.active = true;
  1462. \t\t\tvar choices = oi_data.fe_block.choices;
  1463. \t\t\tvar pick = null;
  1464. \t\t\tfor (var j = 0; j < choices.length; j++) {
  1465. \t\t\t\tif (choices[j].key === fe_block_selected) { pick = choices[j]; break; }
  1466. \t\t\t}
  1467. \t\t\tif (!pick) pick = choices[0];
  1468. \t\t\tresult.choice = pick;
  1469. \t\t\tresult.price  = parseInt(pick.price) || 0;
  1470. \t\t\treturn result;
  1471. \t\t}
  1472. \t\t/**
  1473. \t\t * fe_block ラジオ群を #fe-block-options 要素に描画する.
  1474. \t\t *   active=false (親が「新規にブロック積み」以外) のときは非表示.
  1475. \t\t */
  1476. \t\tfunction renderFeBlockRadios() {
  1477. \t\t\tvar \$box = \$('#fe-block-options');
  1478. \t\t\tif (!\$box.length) return;
  1479. \t\t\tif (!oi_data || !oi_data.fe_block || !oi_data.fe_block.choices) {
  1480. \t\t\t\t\$box.empty().hide();
  1481. \t\t\t\treturn;
  1482. \t\t\t}
  1483. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1484. \t\t\tif (parentIdx < 0) {
  1485. \t\t\t\t\$box.empty().hide();
  1486. \t\t\t\treturn;
  1487. \t\t\t}
  1488. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1489. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  1490. \t\t\tvar visible = (ops[parentIdx] === triggerValue);
  1491. \t\t\tif (!visible) {
  1492. \t\t\t\t\$box.hide();
  1493. \t\t\t\treturn;
  1494. \t\t\t}
  1495. \t\t\tvar fb = oi_data.fe_block;
  1496. \t\t\t\$box.empty();
  1497. \t\t\tvar \$title = \$('<p class=\"rp-section-label\"><strong>' + (fb.title || 'ブロックの種類と段数') + '</strong></p>');
  1498. \t\t\t\$box.append(\$title);
  1499. \t\t\t// 他オプション群と同じ .opt-btn-group / .opt-btn 形式で描画.
  1500. \t\t\t//   生の <label><input type=radio> ... 形式だと CSS 定義が無く
  1501. \t\t\t//   ラベル折り返し・縦ズレ・隣接 opt-btn との間隔不揃いが発生する.
  1502. \t\t\tvar \$list = \$('<div class=\"opt-btn-group\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  1503. \t\t\tfb.choices.forEach(function(ch) {
  1504. \t\t\t\tvar inputId = 'fe_block_' + ch.key;
  1505. \t\t\t\tvar isSel   = (ch.key === fe_block_selected);
  1506. \t\t\t\tvar checked = isSel ? ' checked' : '';
  1507. \t\t\t\tvar selCls  = isSel ? ' is-selected' : '';
  1508. \t\t\t\tvar priceTxt = (parseInt(ch.price) || 0) > 0
  1509. \t\t\t\t\t? ' <span class=\"fe-block-price\" style=\"margin-left:6px;color:#666;font-size:12px;white-space:nowrap;\">(+' + formatter.format(toIncTax(parseInt(ch.price))) + '円 税込)</span>'
  1510. \t\t\t\t\t: '';
  1511. \t\t\t\t\$list.append(
  1512. \t\t\t\t\t'<label class=\"opt-btn' + selCls + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  1513. \t\t\t\t\t'<input type=\"radio\" name=\"fe_block\" id=\"' + inputId + '\" value=\"' + ch.key + '\"' + checked + '>' +
  1514. \t\t\t\t\t'<span class=\"fe-block-label\">' + ch.label + '</span>' +
  1515. \t\t\t\t\tpriceTxt +
  1516. \t\t\t\t\t'</label>'
  1517. \t\t\t\t);
  1518. \t\t\t});
  1519. \t\t\t\$box.append(\$list);
  1520. \t\t\t\$box.show();
  1521. \t\t\t\$box.off('change.fe_block').on('change.fe_block', 'input[type=\"radio\"][name=\"fe_block\"]', function() {
  1522. \t\t\t\tfe_block_selected = \$(this).val();
  1523. \t\t\t\t// is-selected 切替 (opt-btn 形式共通)
  1524. \t\t\t\t\$box.find('label.opt-btn').removeClass('is-selected');
  1525. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  1526. \t\t\t\tmitsumori_simulation('refresh', '');
  1527. \t\t\t});
  1528. \t\t}
  1529. \t\t/**
  1530. \t\t * fe (sale_type=4) で op_data エントリの連動表示制御.
  1531. \t\t *   親「ご希望のフェンス設置方法」の選択値に応じて、
  1532. \t\t *     - 「既存ブロックに穴空け工事が必要ですか?」 entry を表示/非表示
  1533. \t\t *   切替の trigger は親選択値の文字列で判定 (entry index にハードコードしない).
  1534. \t\t */
  1535. \t\tfunction updateFeOpConditionalVisibility() {
  1536. \t\t\tif (SALE_TYPE_ID !== 4) return;
  1537. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  1538. \t\t\tif (parentIdx < 0) return;
  1539. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1540. \t\t\tvar parentSel = ops[parentIdx];
  1541. \t\t\t// 親が「既存ブロックに設置する」 (= off 側) のとき穴空け entry を表示
  1542. \t\t\tvar triggerOffValue = (op_data[parentIdx] && op_data[parentIdx].off) || '既存ブロックに設置する';
  1543. \t\t\t\$('div[data-op-name]').each(function() {
  1544. \t\t\t\tvar n = \$(this).attr('data-op-name') || '';
  1545. \t\t\t\tif (n.indexOf('穴空け') >= 0) {
  1546. \t\t\t\t\tif (parentSel === triggerOffValue) {
  1547. \t\t\t\t\t\t\$(this).show();
  1548. \t\t\t\t\t} else {
  1549. \t\t\t\t\t\t\$(this).hide();
  1550. \t\t\t\t\t}
  1551. \t\t\t\t}
  1552. \t\t\t});
  1553. \t\t}
  1554. \t\t/**
  1555. \t\t * 選択中の施工オプションを集計し、ON選択分の price を合計する.
  1556. \t\t * 戻り値: { total: 合計金額, items: [{name, value, price}, ...] }
  1557. \t\t */
  1558. \t\tfunction collectOptions() {
  1559. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1560. \t\t\tvar total = 0;
  1561. \t\t\tvar items = [];
  1562. \t\t\tfor (var i = 0; i < ops.length; i++) {
  1563. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  1564. \t\t\t\tvar sel = ops[i];
  1565. \t\t\t\tif (!sel) continue;
  1566. \t\t\t\tvar price = parseInt(op_data[i].price) || 0;
  1567. \t\t\t\t// 「ON」選択時のみ加算(OFF や「不要」「商品購入のみ」は加算しない)
  1568. \t\t\t\tvar isOn = (sel === op_data[i].on);
  1569. \t\t\t\titems.push({
  1570. \t\t\t\t\tname:  op_data[i].name,
  1571. \t\t\t\t\tvalue: sel,
  1572. \t\t\t\t\tprice: isOn ? price : 0,
  1573. \t\t\t\t\ton:    op_data[i].on,
  1574. \t\t\t\t\toff:   op_data[i].off,
  1575. \t\t\t\t});
  1576. \t\t\t\tif (isOn) total += price;
  1577. \t\t\t}
  1578. \t\t\t// fe (sale_type=4) のブロック種類×段数 分を items / total に統合.
  1579. \t\t\t// 親オプション「ご希望のフェンス設置方法」 が 「新規にブロック積みを行う」 のとき
  1580. \t\t\t// だけ加算される (collectFeBlock 内で判定済み).
  1581. \t\t\tvar fb = collectFeBlock();
  1582. \t\t\tif (fb.active && fb.choice) {
  1583. \t\t\t\titems.push({
  1584. \t\t\t\t\tname:  (oi_data.fe_block && oi_data.fe_block.title) || 'ブロックの種類と段数',
  1585. \t\t\t\t\tvalue: fb.choice.label,
  1586. \t\t\t\t\tprice: fb.price,
  1587. \t\t\t\t\ton:    fb.choice.label,
  1588. \t\t\t\t\toff:   '',
  1589. \t\t\t\t});
  1590. \t\t\t\ttotal += fb.price;
  1591. \t\t\t}
  1592. \t\t\treturn { total: total, items: items };
  1593. \t\t}
  1594. \t\t/**
  1595. \t\t * free_area 1 エントリ ({w,d,h,m,c,price,unit_price,maker_price,ct,option1,option2})
  1596. \t\t * から sale_type 別に最終金額を算出する.
  1597. \t\t *
  1598. \t\t * 計算式(amount=1 ベース、出口で × 1.10 税込化):
  1599. \t\t *   1 通常        : price + ct + option_sum
  1600. \t\t *   2 補助金窓    : price × set_count + (ct + (set_count-1) × option2) + option_sum
  1601. \t\t *   3 物置        : (price + ct) × daisu + option_sum
  1602. \t\t *   4 フェンス    : price + (maisu-1) × unit_price
  1603. \t\t *                  + ct + max(0, maisu-3) × option1
  1604. \t\t *                  + option_sum   (maisu >= 3)
  1605. \t\t *   5 デッキ      : price + ct + option_sum   (area は表示用、計算非関与)
  1606. \t\t *   6 芝生        : price × ceil(area / (w_m × h_m)) + ct + option_sum
  1607. \t\t *   9 商品のみ    : price のみ(カート quantity 倍で総額)
  1608. \t\t *
  1609. \t\t * fe では option1 を ct_up、um では option2 を ct_up として転用.
  1610. \t\t * tf では w / h にロール幅・長さが格納されており parseLen で数値抽出.
  1611. \t\t *
  1612. \t\t * @param {Object} pp  free_area の 1 行(matrix エントリ)
  1613. \t\t * @param {number} optionTotal  collectOptions().total
  1614. \t\t * @param {Object} ctx  UI 入力 {set_count, daisu, maisu, area, quantityOnly, ...}
  1615. \t\t * @returns {Object} {goukei, price, ct, opt, qty}  すべて税込整数
  1616. \t\t */
  1617. \t\tfunction calcGoukei(pp, optionTotal, ctx) {
  1618. \t\t\tvar basePrice  = parseInt(pp.price)       || 0;
  1619. \t\t\tvar baseCt     = parseInt(pp.ct)          || 0;
  1620. \t\t\tvar unitPrice  = parseInt(pp.unit_price)  || 0;
  1621. \t\t\tvar optSum     = optionTotal;
  1622. \t\t\tvar price      = basePrice;
  1623. \t\t\tvar ct         = baseCt;
  1624. \t\t\tvar qty        = 1;
  1625. \t\t\tvar goukei     = 0;
  1626. \t\t\t// 「商品購入のみ」選択時は工事費・オプションをゼロにする(任意 sale_type で適用)
  1627. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  1628. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  1629. \t\t\tif (purchaseOnly) {
  1630. \t\t\t\tbaseCt = 0;
  1631. \t\t\t\tct     = 0;
  1632. \t\t\t\toptSum = 0;
  1633. \t\t\t}
  1634. \t\t\tswitch (SALE_TYPE_ID) {
  1635. \t\t\t\tcase 2: {  // 補助金・窓 (シンプル表引き方式 2026-05-)
  1636. \t\t\t\t\t// 2026-05 仕様簡素化: 枚数軸を廃止し、subtype に枚数を内包.
  1637. \t\t\t\t\t// pp.price / pp.ct は (W, H, ガラス, subtype) の単一価格.
  1638. \t\t\t\t\t// 複数枚をまとめて買う場合はカート quantity で表現.
  1639. \t\t\t\t\tqty    = 1;
  1640. \t\t\t\t\tprice  = basePrice;
  1641. \t\t\t\t\tct     = baseCt;
  1642. \t\t\t\t\tgoukei = price + ct + optSum;
  1643. \t\t\t\t\tbreak;
  1644. \t\t\t\t}
  1645. \t\t\t\tcase 3: {  // 物置・ゴミステーション
  1646. \t\t\t\t\tqty   = Math.max(1, parseInt(ctx.daisu) || 1);
  1647. \t\t\t\t\tprice = basePrice * qty;
  1648. \t\t\t\t\tct    = baseCt * qty;
  1649. \t\t\t\t\tgoukei = price + ct + optSum;
  1650. \t\t\t\t\tbreak;
  1651. \t\t\t\t}
  1652. \t\t\t\tcase 4: {  // フェンス・組み立て式(maisu ≥ 3、base_amount = 3)
  1653. \t\t\t\t\t// scraper は amount=3 を base にしているので pp.price = price(3),
  1654. \t\t\t\t\t// pp.unit_price = price(4) - price(3).
  1655. \t\t\t\t\tqty   = Math.max(3, parseInt(ctx.maisu) || 3);
  1656. \t\t\t\t\tprice = basePrice + (qty - 3) * unitPrice;
  1657. \t\t\t\t\t// option1 が ct_up (4枚目以降の増分). 未設定なら ct 固定動作
  1658. \t\t\t\t\tvar ctUp1 = parseInt(pp.option1) || 0;
  1659. \t\t\t\t\tct = baseCt + Math.max(0, qty - 3) * ctUp1;
  1660. \t\t\t\t\t// fe_block(ブロック積み段数): collectOptions が base(3枚分)を optSum に
  1661. \t\t\t\t\t// 算入済み. ブロック費も本体同様に枚数連動するため、4枚目以降は 1枚毎に
  1662. \t\t\t\t\t// choice.unit_price(= block(4)-block(3)) を加算する.
  1663. \t\t\t\t\t// (顧客指摘「何枚施工でも増える金額が同じ」の是正。unit_price 未設定の
  1664. \t\t\t\t\t//  旧データでは +0 で従来動作。)
  1665. \t\t\t\t\tif (!purchaseOnly) {
  1666. \t\t\t\t\t\tvar fbC = collectFeBlock();
  1667. \t\t\t\t\t\tif (fbC.active && fbC.choice) {
  1668. \t\t\t\t\t\t\toptSum += Math.max(0, qty - 3) * (parseInt(fbC.choice.unit_price) || 0);
  1669. \t\t\t\t\t\t}
  1670. \t\t\t\t\t}
  1671. \t\t\t\t\tgoukei = price + ct + optSum;
  1672. \t\t\t\t\tbreak;
  1673. \t\t\t\t}
  1674. \t\t\t\tcase 5: {  // ウッドデッキ・タイルデッキ
  1675. \t\t\t\t\t// area は担当者向けの参考値として保持(計算には使わない)
  1676. \t\t\t\t\tqty    = 1;
  1677. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  1678. \t\t\t\t\tprice  = basePrice;
  1679. \t\t\t\t\tct     = baseCt;
  1680. \t\t\t\t\tbreak;
  1681. \t\t\t\t}
  1682. \t\t\t\tcase 6: {  // 芝生・人工芝(ロール単位)
  1683. \t\t\t\t\t// pp.w \"1m\", pp.h \"10m\" から数値抽出
  1684. \t\t\t\t\tvar w_m = parseLen(pp.w);
  1685. \t\t\t\t\tvar h_m = parseLen(pp.h);
  1686. \t\t\t\t\tvar rollSize = w_m * h_m;
  1687. \t\t\t\t\tif (!rollSize || rollSize <= 0) rollSize = 1;
  1688. \t\t\t\t\t// 施工サイズ(面積)があれば必要枚数を自動算出。無ければ直接指定の枚数を使う。
  1689. \t\t\t\t\tvar area  = parseFloat(ctx.area) || 0;
  1690. \t\t\t\t\tif (area > 0) {
  1691. \t\t\t\t\t\tqty = Math.max(1, Math.ceil(area / rollSize));
  1692. \t\t\t\t\t} else {
  1693. \t\t\t\t\t\tqty = Math.max(1, parseInt(ctx.tf_qty) || 1);
  1694. \t\t\t\t\t}
  1695. \t\t\t\t\tprice  = basePrice * qty;
  1696. \t\t\t\t\tct     = baseCt;
  1697. \t\t\t\t\tgoukei = price + ct + optSum;
  1698. \t\t\t\t\tbreak;
  1699. \t\t\t\t}
  1700. \t\t\t\tcase 7: {  // 数量買い・基本工事費固定(gf ガーデンファニチャー / st 石材)
  1701. \t\t\t\t\tqty    = Math.max(1, parseInt(ctx.suuryou) || 1);
  1702. \t\t\t\t\tprice  = basePrice * qty;
  1703. \t\t\t\t\tct     = baseCt;                 // ct は固定(数量に依らない)
  1704. \t\t\t\t\tgoukei = price + ct + optSum;
  1705. \t\t\t\t\tbreak;
  1706. \t\t\t\t}
  1707. \t\t\t\tcase 9: {  // 商品のみ購入
  1708. \t\t\t\t\t// カート側で quantity × unit price するため goukei は単品価格
  1709. \t\t\t\t\tqty    = parseInt(ctx.quantityOnly) || 1;
  1710. \t\t\t\t\tprice  = basePrice;
  1711. \t\t\t\t\tct     = 0;
  1712. \t\t\t\t\toptSum = 0;
  1713. \t\t\t\t\tgoukei = price;
  1714. \t\t\t\t\tbreak;
  1715. \t\t\t\t}
  1716. \t\t\t\tdefault: {  // 1: 通常(カーポート等、matrix 選択のみ)
  1717. \t\t\t\t\tqty    = 1;
  1718. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  1719. \t\t\t\t\tbreak;
  1720. \t\t\t\t}
  1721. \t\t\t}
  1722. \t\t\t// 出口で税込化(pp.price/pp.ct/op_data.price はすべて税抜で保存されている前提)
  1723. \t\t\treturn {
  1724. \t\t\t\tgoukei: toIncTax(goukei),
  1725. \t\t\t\tprice:  toIncTax(price),
  1726. \t\t\t\tct:     toIncTax(ct),
  1727. \t\t\t\topt:    toIncTax(optSum),
  1728. \t\t\t\tqty:    qty,
  1729. \t\t\t};
  1730. \t\t}
  1731. \t\t/**
  1732. \t\t * 寸法文字列から「メートル単位の数値」を抽出する.
  1733. \t\t *
  1734. \t\t * 単位は m / cm / mm を認識し、いずれも m 単位に正規化して返す.
  1735. \t\t * 単位が無い場合は m 単位とみなす(旧 tf データ \"1m\" \"10m\" との互換).
  1736. \t\t * 数値が見つからない場合は 0 を返す(呼び出し側で fallback).
  1737. \t\t *
  1738. \t\t * 例:
  1739. \t\t *   \"1m\"     → 1
  1740. \t\t *   \"100cm\"  → 1   (2026-06 以降の m → cm 正規化に対応)
  1741. \t\t *   \"200cm\"  → 2
  1742. \t\t *   \"5.5m\"   → 5.5
  1743. \t\t *   \"1000mm\" → 1
  1744. \t\t *   \"\"       → 0
  1745. \t\t */
  1746. \t\tfunction parseLen(s) {
  1747. \t\t\tif (!s) return 0;
  1748. \t\t\tvar str = String(s);
  1749. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)\\s*(mm|cm|m)?/i);
  1750. \t\t\tif (!m) return 0;
  1751. \t\t\tvar n = parseFloat(m[1]);
  1752. \t\t\tif (isNaN(n)) return 0;
  1753. \t\t\tvar unit = (m[2] || 'm').toLowerCase();
  1754. \t\t\tif (unit === 'cm') return n / 100;
  1755. \t\t\tif (unit === 'mm') return n / 1000;
  1756. \t\t\treturn n;  // 'm' or no unit
  1757. \t\t}
  1758. \t\t// pp は autoSelectFirstColor 等からも参照するので global にする
  1759. \t\tvar pp = ";
  1760.         // line 1601
  1761.         echo (isset($context["pp"]) || array_key_exists("pp"$context) ? $context["pp"] : (function () { throw new RuntimeError('Variable "pp" does not exist.'1601$this->source); })());
  1762.         echo ";
  1763. \t\t// sale_type=2 の幅 / 高さ ladder (Twig p_w / p_h を JS で参照するため).
  1764. \t\t// 入力 mm 値を pp の幅・高さバケット文字列にマッピングする際の元データ.
  1765. \t\t// p_w / p_h は連想配列で来ることがあるため Object.values で配列化する.
  1766. \t\tvar PP_W_LADDER = Object.values(";
  1767.         // line 1606
  1768.         echo json_encode(((array_key_exists("p_w"$context)) ? (_twig_default_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'1606$this->source); })()), [])) : ([])));
  1769.         echo " || {});
  1770. \t\tvar PP_H_LADDER = Object.values(";
  1771.         // line 1607
  1772.         echo json_encode(((array_key_exists("p_h"$context)) ? (_twig_default_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'1607$this->source); })()), [])) : ([])));
  1773.         echo " || {});
  1774. \t\t/* ============================================================
  1775. \t\t   sale_type=2 (補助金窓) 専用: 複数タイプ集計 & 補助金計算
  1776. \t\t   ============================================================
  1777. \t\t   - 入力 UI: #window-types-container 配下の .window-type-block
  1778. \t\t   - 補助金根拠: 先進的窓リノベ2026事業
  1779. \t\t     https://window-renovation2026.env.go.jp/construction/inner-window.html
  1780. \t\t   - 価格軸: (subtype, w, h, glass, color) で pp を lookup
  1781. \t\t   - 1 商品 = 1 明細 にまとめ、内訳 JSON を別途保存予定 (cart 連携は後続タスク)
  1782. \t\t   ============================================================ */
  1783. \t\t// 補助金マトリクス: [住宅区分][性能][サイズ区分] → 1 箇所あたり金額 (税抜・端数なし)
  1784. \t\tvar WINDOW_SUBSIDY_MATRIX = {
  1785. \t\t\tdetached:  { // 戸建住宅・延床240㎡以下の非住宅
  1786. \t\t\t\tP: { G: 140000, L: 89000, M: 58000, S: 36000 },
  1787. \t\t\t\tS: { G: 76000,  L: 52000, M: 34000, S: 22000 }
  1788. \t\t\t},
  1789. \t\t\tapartment: { // 低層・中高層集合住宅・240㎡超の非住宅
  1790. \t\t\t\tP: { G: 152000, L: 98000, M: 64000, S: 40000 },
  1791. \t\t\t\tS: { G: 83000,  L: 57000, M: 37000, S: 24000 }
  1792. \t\t\t}
  1793. \t\t};
  1794. \t\t// 住宅区分: 画面 UI (input[name=\"window_housing_type\"]) から取得する.
  1795. \t\t// 既定値は PFC meta_key=\"住宅区分\" を fallback (未設定なら '戸建').
  1796. \t\tvar HOUSING_TYPE_DEFAULT = ";
  1797.         // line 1633
  1798.         echo json_encode(_twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1633$this->source); })()), "id", [], "any"falsefalsefalse1633), "住宅区分"), "戸建"));
  1799.         echo ";
  1800. \t\tfunction getCurrentHousingKey() {
  1801. \t\t\tvar el = document.querySelector('input[name=\"window_housing_type\"]:checked');
  1802. \t\t\tvar v  = el ? el.value : HOUSING_TYPE_DEFAULT;
  1803. \t\t\treturn (v === '集合住宅') ? 'apartment' : 'detached';
  1804. \t\t}
  1805. \t\t// 商品シリーズ自動判定 (Product.name から)
  1806. \t\t// 根拠カタログ: YKK AP「ウチリモ」XAAAA-H26-067-1 (2026.04), 同「LiteU」XAAAA-H16-088-2,
  1807. \t\t//              三協アルミ「プラメイクEII」0142_STJ1931L, LIXIL「インプラス」(既知)
  1808. \t\tvar PRODUCT_NAME_RAW = ";
  1809.         // line 1643
  1810.         echo json_encode(((twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "name", [], "any"truetruefalse1643)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "name", [], "any"falsefalsefalse1643), "")) : ("")));
  1811.         echo ";
  1812. \t\tfunction detectProductSeries(name) {
  1813. \t\t\tif (!name) return null;
  1814. \t\t\tif (/ウチリモ/.test(name)) return 'uchirimo';
  1815. \t\t\tif (/プラマード\\s*U/i.test(name)) return 'pramado_u';
  1816. \t\t\tif (/インプラス/.test(name)) return 'inplus';
  1817. \t\t\tif (/プラメイク\\s*EII|プラメイクEII/i.test(name)) return 'plamake_eii';
  1818. \t\t\tif (/LiteU/i.test(name)) return 'lite_u';
  1819. \t\t\treturn null;
  1820. \t\t}
  1821. \t\t// シリーズ上限グレード:
  1822. \t\t//   'P'  = SS/P まで到達可能 (真空断熱ガラス採用シリーズ)
  1823. \t\t//   'S'  = Low-E 複層止まり (真空断熱ガラスのラインなし)
  1824. \t\t//   null = 単板のみ → 補助金対象外
  1825. \t\tvar SERIES_GRADE_CAP = {
  1826. \t\t\tuchirimo:    'P',
  1827. \t\t\tpramado_u:   'P',
  1828. \t\t\tinplus:      'S',
  1829. \t\t\tplamake_eii: 'S',
  1830. \t\t\tlite_u:      null
  1831. \t\t};
  1832. \t\tvar DETECTED_SERIES = detectProductSeries(PRODUCT_NAME_RAW);
  1833. \t\tvar SERIES_GRADE_CAP_VAL = (DETECTED_SERIES !== null && Object.prototype.hasOwnProperty.call(SERIES_GRADE_CAP, DETECTED_SERIES))
  1834. \t\t\t? SERIES_GRADE_CAP[DETECTED_SERIES]
  1835. \t\t\t: undefined;
  1836. \t\t// 商品単位グレード上限 (PFC `meta_key=補助金グレード上限` で個別上書き)
  1837. \t\t// 値: 'P' / 'SS' / 'S' / '対象外' / '無' / 'NONE' / 空文字 (未指定)
  1838. \t\tvar PRODUCT_GRADE_CAP_RAW = ";
  1839.         // line 1671
  1840.         echo json_encode(_twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'1671$this->source); })()), "id", [], "any"falsefalsefalse1671), "補助金グレード上限"), ""));
  1841.         echo ";
  1842. \t\tfunction normalizeGradeCap(v) {
  1843. \t\t\tif (v === null || v === undefined || v === '') return undefined;
  1844. \t\t\tvar s = String(v).trim().toUpperCase();
  1845. \t\t\tif (s === 'NONE' || s === '対象外' || s === '無') return null;
  1846. \t\t\tif (s === 'P' || s === 'SS') return 'P';
  1847. \t\t\tif (s === 'S') return 'S';
  1848. \t\t\treturn undefined;
  1849. \t\t}
  1850. \t\tvar PRODUCT_GRADE_CAP = normalizeGradeCap(PRODUCT_GRADE_CAP_RAW);
  1851. \t\t// 窓種 (subtype = option1) ごとのグレード上限.
  1852. \t\t// 根拠: YKK AP「ウチリモ」業務用 (XAAAA-H26-067-1) の窓種別ラインナップで
  1853. \t\t//      真空ガラス (Glavenir) の設定有無を確認:
  1854. \t\t//        引違い窓 (2/3/4枚建) / 浴室仕様 引違い窓 / FIX窓        → P 到達可能
  1855. \t\t//        内開き窓 (居室/浴室) / 開き窓テラス / テラスドア類       → 真空ガラスなし → S 止まり
  1856. \t\tfunction detectSubtypeGradeCap(subtype) {
  1857. \t\t\tif (!subtype) return undefined;
  1858. \t\t\tvar s = String(subtype);
  1859. \t\t\tif (/内開|開き窓テラス|テラスドア|開き戸/.test(s)) return 'S';
  1860. \t\t\treturn undefined;
  1861. \t\t}
  1862. \t\t// クリップ: 強さは 'P' > 'S' > null (対象外). cap=null は強制対象外, cap=undefined は無効化なし.
  1863. \t\tfunction clipGradeBy(grade, cap) {
  1864. \t\t\tif (cap === undefined) return grade;
  1865. \t\t\tif (cap === null)      return null;
  1866. \t\t\tif (grade === null)    return null;
  1867. \t\t\tif (cap === 'S' && grade === 'P') return 'S';
  1868. \t\t\treturn grade;
  1869. \t\t}
  1870. \t\tfunction finalizeGlassGrade(raw, subtype) {
  1871. \t\t\tvar g = clipGradeBy(raw, SERIES_GRADE_CAP_VAL);
  1872. \t\t\tg     = clipGradeBy(g,   detectSubtypeGradeCap(subtype));
  1873. \t\t\tg     = clipGradeBy(g,   PRODUCT_GRADE_CAP);
  1874. \t\t\treturn g;
  1875. \t\t}
  1876. \t\t/**
  1877. \t\t * ガラスタイプ名から性能区分 'P' (SS, Uw≤1.1) / 'S' (Uw≤1.5) / null を判別.
  1878. \t\t * null = 補助対象外.
  1879. \t\t *
  1880. \t\t * 根拠: YKK AP「ウチリモ 内窓」業務用カタログ (XAAAA-H26-069-1) で
  1881. \t\t *       P (SS) は真空断熱ガラスのみ、Low-E はアルゴン入りでも S 止まり、
  1882. \t\t *       Low-E ガス無 + 型ガラス / フロストは 2026年4月で対象外、
  1883. \t\t *       が確認できた。アルゴン入り Low-E を P 判定する旧ルールは誤りだった。
  1884. \t\t *
  1885. \t\t * シリーズによっては P がそもそも存在しない (LIXIL インプラスは S 一律)
  1886. \t\t * ため、最終的には PFC で商品単位の上限を上書きできる仕組みが必要。
  1887. \t\t */
  1888. \t\tfunction detectGlassPerformance(glassName) {
  1889. \t\t\tif (!glassName) return null;
  1890. \t\t\tvar n = String(glassName);
  1891. \t\t\t// 補助対象外: 単板 / 和紙調 / 防音 / 防犯 / 型ガラス・フロスト (Low-E ガス無の型は 2026/4 で対象外)
  1892. \t\t\tif (/単ガラス|単板|和紙調|防音|防犯|複層\\/型|型ガラス|フロスト/.test(n)) return null;
  1893. \t\t\t// P (SS): 真空断熱ガラスのみ
  1894. \t\t\tif (/真空断熱/.test(n)) return 'P';
  1895. \t\t\t// S: Low-E 系のみ (アルゴン入りでも S 止まり)
  1896. \t\t\tif (/Low-?E/i.test(n)) return 'S';
  1897. \t\t\t// 一般複層 / ブラインドイン複層 / 複層強化 など Low-E 無しの複層は補助対象外
  1898. \t\t\treturn null;
  1899. \t\t}
  1900. \t\t/**
  1901. \t\t * 幅 mm × 高さ mm からサイズ区分 'G' (≥4.0㎡) / 'L' (2.8-3.9) / 'M' (1.6-2.7) / 'S' (0.2-1.5) / null.
  1902. \t\t * null = 補助対象外 (0.2㎡ 未満).
  1903. \t\t */
  1904. \t\tfunction detectSizeClass(w_mm, h_mm) {
  1905. \t\t\tvar w = parseFloat(w_mm) || 0;
  1906. \t\t\tvar h = parseFloat(h_mm) || 0;
  1907. \t\t\tif (w <= 0 || h <= 0) return null;
  1908. \t\t\tvar area = (w * h) / 1000000.0;
  1909. \t\t\tif (area < 0.2) return null;
  1910. \t\t\tif (area < 1.6) return 'S';
  1911. \t\t\tif (area < 2.8) return 'M';
  1912. \t\t\tif (area < 4.0) return 'L';
  1913. \t\t\treturn 'G';
  1914. \t\t}
  1915. \t\tfunction lookupSubsidyAmount(performance, sizeClass) {
  1916. \t\t\tif (!performance || !sizeClass) return 0;
  1917. \t\t\tvar t = WINDOW_SUBSIDY_MATRIX[getCurrentHousingKey()];
  1918. \t\t\tif (!t || !t[performance]) return 0;
  1919. \t\t\treturn t[performance][sizeClass] || 0;
  1920. \t\t}
  1921. \t\t/**
  1922. \t\t * mm 入力値を ladder バケット文字列に変換する.
  1923. \t\t *   bucketizeMm(1750, [\"100cm まで\",\"150cm まで\",\"200cm まで\",\"300cm まで\"]) → \"200cm まで\"
  1924. \t\t * - 入力が空 or 0 のときはそのまま返す (未入力扱い)
  1925. \t\t * - 入力がラダー最大を超えるときは最大バケットを返す (= 価格上限の保護)
  1926. \t\t * - 入力文字列が既にラダーラベルそのものなら無変換 (互換のため)
  1927. \t\t */
  1928. \t\tfunction bucketizeMm(input, ladder) {
  1929. \t\t\tif (!input && input !== 0) return '';
  1930. \t\t\tif (!ladder || ladder.length === 0) return input;
  1931. \t\t\tvar s = String(input).trim();
  1932. \t\t\tif (s === '') return '';
  1933. \t\t\tif (ladder.indexOf(s) >= 0) return s;
  1934. \t\t\tvar mm = parseMm(s);
  1935. \t\t\tif (mm <= 0) return s;
  1936. \t\t\tvar withMax = ladder.map(function(b) { return { label: b, max: parseMm(b) }; });
  1937. \t\t\twithMax.sort(function(a, b) { return a.max - b.max; });
  1938. \t\t\tfor (var i = 0; i < withMax.length; i++) {
  1939. \t\t\t\tif (mm <= withMax[i].max) return withMax[i].label;
  1940. \t\t\t}
  1941. \t\t\treturn withMax[withMax.length - 1].label;
  1942. \t\t}
  1943. \t\t/**
  1944. \t\t * pp 配列から該当 1 行を返す. 完全一致優先、見つからなければ最初の候補.
  1945. \t\t * 軸: subtype (option1) / w / h / m / c. axisMatch は既存ロジックと同じ.
  1946. \t\t * sale_type=2 では pw_val / ph_val に mm 数値が来るため、内部で bucketizeMm
  1947. \t\t * を通してから既存マッチングに渡す.
  1948. \t\t */
  1949. \t\tfunction lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val) {
  1950. \t\t\tif (!pp || pp.length === 0) return null;
  1951. \t\t\tvar pw_bucket = bucketizeMm(pw_val, PP_W_LADDER);
  1952. \t\t\tvar ph_bucket = bucketizeMm(ph_val, PP_H_LADDER);
  1953. \t\t\tvar axMatch = function(input, value) {
  1954. \t\t\t\treturn input == value || input === '指定なし' || value === '' || value == null;
  1955. \t\t\t};
  1956. \t\t\tvar colMatch = function(input, value) {
  1957. \t\t\t\tif (axMatch(input, value)) return true;
  1958. \t\t\t\tif (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  1959. \t\t\t\t\treturn value.split('/').some(function(s) { return s.trim() === input; });
  1960. \t\t\t\t}
  1961. \t\t\t\treturn false;
  1962. \t\t\t};
  1963. \t\t\tvar candidates = pp.filter(function(el) {
  1964. \t\t\t\treturn axMatch(pw_bucket, el.w)
  1965. \t\t\t\t\t&& axMatch(ph_bucket, el.h)
  1966. \t\t\t\t\t&& axMatch(pm_val, el.m)
  1967. \t\t\t\t\t&& axMatch(subtype, el.option1);
  1968. \t\t\t});
  1969. \t\t\tfor (var i = 0; i < candidates.length; i++) {
  1970. \t\t\t\tif (colMatch(pc_val, candidates[i].c)) return candidates[i];
  1971. \t\t\t}
  1972. \t\t\treturn candidates[0] || null;
  1973. \t\t}
  1974. \t\t/**
  1975. \t\t * \"1000mm\" / \"200cm\" / \"1.0m\" / 単位なし → mm に正規化して返す.
  1976. \t\t * UI 上の「200cm まで」等の文字列をそのまま渡せるようにする.
  1977. \t\t */
  1978. \t\tfunction parseMm(s) {
  1979. \t\t\tif (!s) return 0;
  1980. \t\t\tvar str = String(s);
  1981. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)/);
  1982. \t\t\tif (!m) return 0;
  1983. \t\t\tvar num = parseFloat(m[1]);
  1984. \t\t\tif (/mm/i.test(str)) return num;
  1985. \t\t\tif (/cm/i.test(str)) return num * 10;
  1986. \t\t\tif (/(^|\\d)\\s*m(\$|\\W)/i.test(str)) return num * 1000;
  1987. \t\t\treturn num;
  1988. \t\t}
  1989. \t\t/**
  1990. \t\t * 1 タイプブロックから入力を読み、pp lookup → 単価・補助金額を計算して返す.
  1991. \t\t * incomplete=true: 軸のどれかが未選択 → 計算しない (UI で「未選択」を示すため).
  1992. \t\t */
  1993. \t\tfunction collectWindowTypeRow(block) {
  1994. \t\t\tvar get = function(axis) {
  1995. \t\t\t\t// radio / checkbox は :checked、それ以外 (number/text) は値そのまま.
  1996. \t\t\t\tvar radio = block.querySelector('input[data-axis=\"' + axis + '\"]:checked');
  1997. \t\t\t\tif (radio) return radio.value;
  1998. \t\t\t\tvar any = block.querySelector('input[data-axis=\"' + axis + '\"]');
  1999. \t\t\t\tif (!any) return '';
  2000. \t\t\t\tif (any.type === 'radio' || any.type === 'checkbox') return '';
  2001. \t\t\t\treturn (any.value || '').trim();
  2002. \t\t\t};
  2003. \t\t\tvar setqtyEl = block.querySelector('input[data-axis=\"setqty\"]');
  2004. \t\t\tvar subtype = get('subtype');
  2005. \t\t\tvar pw_val  = get('pw');
  2006. \t\t\tvar ph_val  = get('ph');
  2007. \t\t\tvar pm_val  = get('pm');
  2008. \t\t\tvar pc_val  = get('pc');
  2009. \t\t\tvar setqty  = setqtyEl ? Math.max(1, parseInt(setqtyEl.value) || 1) : 1;
  2010. \t\t\tvar row = {
  2011. \t\t\t\tsubtype: subtype, pw: pw_val, ph: ph_val, pm: pm_val, pc: pc_val, setqty: setqty,
  2012. \t\t\t\tunit_price_exc: 0, unit_ct_exc: 0, subsidy: 0,
  2013. \t\t\t\tsize_class: null, glass_perf: null,
  2014. \t\t\t\tincomplete: false
  2015. \t\t\t};
  2016. \t\t\t// p_option1 / p_w / p_h / p_m / color のいずれかが商品データに無いときは未選択でも完了扱いにする.
  2017. \t\t\t// (例: 商品によっては subtype が無い場合がある)
  2018. \t\t\tvar hasSubtype = !!block.querySelector('input[data-axis=\"subtype\"]');
  2019. \t\t\tvar hasPw      = !!block.querySelector('input[data-axis=\"pw\"]');
  2020. \t\t\tvar hasPh      = !!block.querySelector('input[data-axis=\"ph\"]');
  2021. \t\t\tvar hasPm      = !!block.querySelector('input[data-axis=\"pm\"]');
  2022. \t\t\tvar hasPc      = !!block.querySelector('input[data-axis=\"pc\"]');
  2023. \t\t\tif ((hasSubtype && !subtype) || (hasPw && !pw_val) || (hasPh && !ph_val)
  2024. \t\t\t    || (hasPm && !pm_val)  || (hasPc && !pc_val)) {
  2025. \t\t\t\trow.incomplete = true;
  2026. \t\t\t\treturn row;
  2027. \t\t\t}
  2028. \t\t\tvar ppRow = lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val);
  2029. \t\t\tif (ppRow) {
  2030. \t\t\t\trow.unit_price_exc = parseInt(ppRow.price) || 0;
  2031. \t\t\t\trow.unit_ct_exc    = parseInt(ppRow.ct)    || 0;
  2032. \t\t\t}
  2033. \t\t\t// ガラス名検出 → シリーズ上限 → subtype 上限 → 商品上限 の順で min クリップ.
  2034. \t\t\t// 例: LiteU (SERIES_GRADE_CAP_VAL=null) は Low-E でも null に落ちて補助対象外.
  2035. \t\t\t// 例: ウチリモの「内開き窓」subtype は真空ガラスでも S に落ちる.
  2036. \t\t\trow.glass_perf = finalizeGlassGrade(detectGlassPerformance(pm_val), subtype);
  2037. \t\t\trow.size_class = detectSizeClass(parseMm(pw_val), parseMm(ph_val));
  2038. \t\t\trow.subsidy    = lookupSubsidyAmount(row.glass_perf, row.size_class);
  2039. \t\t\treturn row;
  2040. \t\t}
  2041. \t\t/**
  2042. \t\t * sale_type=2 用集計: 全タイプから合計を出し DOM 更新.
  2043. \t\t * 計算式 (税抜→税込で出口で 1.10 倍):
  2044. \t\t *   商品金額 = Σ(各タイプ単価 × set_qty)
  2045. \t\t *   基本工事費 = 1 回分 (各タイプ pp.ct のうち最初に得た非ゼロ値)
  2046. \t\t *   補助金合計 = Σ(各タイプ補助金 × set_qty)
  2047. \t\t *   実質支払額 = (商品+ct+option) 税込 - 補助金合計
  2048. \t\t */
  2049. \t\tfunction recalcAllForSaleType2() {
  2050. \t\t\tif (typeof SALE_TYPE_ID === 'undefined' || SALE_TYPE_ID != 2) return;
  2051. \t\t\tif (!pp || pp.length === 0) {
  2052. \t\t\t\t\$('#mitsumori_message').text('価格データ準備中');
  2053. \t\t\t\t\$('#mitsumori_btn').hide();
  2054. \t\t\t\t['#mitsumori_goukei','#mitsumori_off','#mitsumori_price','#maker_price',
  2055. \t\t\t\t '#mitsumori_ct','#mitsumori_option','#mitsumori_kei','#mitsumori_shoukei','#mitsumori_tax']
  2056. \t\t\t\t .forEach(function(s){ \$(s).text('---円'); });
  2057. \t\t\t\treturn;
  2058. \t\t\t}
  2059. \t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  2060. \t\t\tif (blocks.length === 0) return;
  2061. \t\t\tvar rows = [];
  2062. \t\t\tvar hasIncomplete = false;
  2063. \t\t\tvar baseCt = 0;
  2064. \t\t\tvar hasAnyPriced = false;
  2065. \t\t\tblocks.forEach(function(b) {
  2066. \t\t\t\tvar r = collectWindowTypeRow(b);
  2067. \t\t\t\trows.push({ block: b, row: r });
  2068. \t\t\t\tif (r.incomplete) hasIncomplete = true;
  2069. \t\t\t\tif (r.unit_ct_exc > 0 && baseCt === 0) baseCt = r.unit_ct_exc;
  2070. \t\t\t\tif (r.unit_price_exc > 0) hasAnyPriced = true;
  2071. \t\t\t\tvar subSpan = b.querySelector('.wt-subsidy-amount');
  2072. \t\t\t\tif (subSpan) subSpan.textContent = r.incomplete ? '―' : Math.round(r.subsidy * r.setqty).toLocaleString();
  2073. \t\t\t});
  2074. \t\t\tif (hasIncomplete || !hasAnyPriced) {
  2075. \t\t\t\t\$('#mitsumori_message').text('窓タイプを選択してください');
  2076. \t\t\t\t\$('#mitsumori_btn').hide();
  2077. \t\t\t\treturn;
  2078. \t\t\t}
  2079. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  2080. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  2081. \t\t\tvar sumPriceExc = 0, sumSubsidy = 0, totalPanes = 0;
  2082. \t\t\trows.forEach(function(item) {
  2083. \t\t\t\tvar r = item.row;
  2084. \t\t\t\tsumPriceExc += r.unit_price_exc * r.setqty;
  2085. \t\t\t\tsumSubsidy  += r.subsidy * r.setqty;
  2086. \t\t\t\tif (r.unit_price_exc > 0) totalPanes += r.setqty;
  2087. \t\t\t});
  2088. \t\t\t// 内窓 工事費(顧客最終回答): 1枚目 22,000円 + 2枚目以降 1枚あたり +5,000円(税込表示額)。
  2089. \t\t\t// 既存パイプライン整合のため税抜(ctExc)も用意(税行 taxAmt 用)。商品購入のみは 0。
  2090. \t\t\tvar WINDOW_CT_BASE = 22000, WINDOW_CT_ADD = 5000;
  2091. \t\t\tvar ctIncTarget = purchaseOnly ? 0 : (WINDOW_CT_BASE + Math.max(0, totalPanes - 1) * WINDOW_CT_ADD);
  2092. \t\t\tvar ctExc  = purchaseOnly ? 0 : Math.round(ctIncTarget / (1 + TAX_RATE));
  2093. \t\t\tvar optExc = purchaseOnly ? 0 : (collectOptions().total || 0);
  2094. \t\t\tvar sumPriceInc = Math.round(sumPriceExc * (1 + TAX_RATE));
  2095. \t\t\tvar ctInc       = ctIncTarget;
  2096. \t\t\tvar optInc      = Math.round(optExc * (1 + TAX_RATE));
  2097. \t\t\tvar goukeiInc   = sumPriceInc + ctInc + optInc;
  2098. \t\t\t// 窓リノベ2026 申請条件:
  2099. \t\t\t//   - 補助金合計 ≥ 50,000 円 (5 万円未満は申請不可 → 還元 0 円扱い)
  2100. \t\t\t//   - 1 戸あたり上限 1,000,000 円 (住宅・非住宅240㎡以下)
  2101. \t\t\t//     ※ 非住宅 240㎡超の 10,000,000 円上限は対象外 (商品設計時に別扱い想定)
  2102. \t\t\tvar SUBSIDY_MIN_AMOUNT = 50000;
  2103. \t\t\tvar SUBSIDY_MAX_PER_UNIT = 1000000;
  2104. \t\t\tvar subsidyRawSum = sumSubsidy;
  2105. \t\t\tvar subsidyEligible = subsidyRawSum >= SUBSIDY_MIN_AMOUNT;
  2106. \t\t\tvar subsidyAmt = 0;
  2107. \t\t\tvar subsidyNote = '';
  2108. \t\t\tif (subsidyEligible) {
  2109. \t\t\t\tif (subsidyRawSum > SUBSIDY_MAX_PER_UNIT) {
  2110. \t\t\t\t\tsubsidyAmt = SUBSIDY_MAX_PER_UNIT;
  2111. \t\t\t\t\tsubsidyNote = '※補助上限 ' + SUBSIDY_MAX_PER_UNIT.toLocaleString()
  2112. \t\t\t\t\t\t+ '円 超過分は控除対象外(補助金合計 ' + subsidyRawSum.toLocaleString() + '円)';
  2113. \t\t\t\t} else {
  2114. \t\t\t\t\tsubsidyAmt = subsidyRawSum;
  2115. \t\t\t\t}
  2116. \t\t\t} else if (subsidyRawSum > 0) {
  2117. \t\t\t\tsubsidyNote = '※補助金合計が 5 万円未満のため申請対象外です('
  2118. \t\t\t\t\t+ subsidyRawSum.toLocaleString() + '円)';
  2119. \t\t\t} else if (SERIES_GRADE_CAP_VAL === null) {
  2120. \t\t\t\t// LiteU 等の単板構成シリーズ: グレード判定で必ず null になる
  2121. \t\t\t\tsubsidyNote = '※本商品は補助金(先進的窓リノベ2026事業)対象外です';
  2122. \t\t\t} else if (PRODUCT_GRADE_CAP === null) {
  2123. \t\t\t\tsubsidyNote = '※本商品は補助金対象外として登録されています';
  2124. \t\t\t}
  2125. \t\t\tvar implementedInc = Math.max(0, goukeiInc - subsidyAmt);
  2126. \t\t\tvar taxAmt      = Math.round((sumPriceExc + ctExc + optExc) * TAX_RATE);
  2127. \t\t\t\$('#mitsumori_message').text(subsidyNote);
  2128. \t\t\t\$('#mitsumori_btn').show();
  2129. \t\t\t\$('#mitsumori_goukei').text(goukeiInc.toLocaleString() + '円');
  2130. \t\t\t\$('#mitsumori_price').text(sumPriceInc.toLocaleString() + '円');
  2131. \t\t\t\$('#mitsumori_ct').text(ctInc.toLocaleString() + '円');
  2132. \t\t\t\$('#mitsumori_option').text(optInc.toLocaleString() + '円');
  2133. \t\t\t\$('#mitsumori_off').text((subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円');
  2134. \t\t\t\$('#maker_price').text('---円'); // 補助金窓では未使用
  2135. \t\t\t\$('#mitsumori_kei').text(goukeiInc.toLocaleString() + '円');
  2136. \t\t\t\$('#mitsumori_shoukei').text(implementedInc.toLocaleString() + '円');
  2137. \t\t\t\$('#mitsumori_tax').text(taxAmt.toLocaleString() + '円');
  2138. \t\t\t// 内訳を mitsumori_json に詰めて hidden input にセット (PDF / カート連携用)
  2139. \t\t\tvar window_types = rows.map(function(item) {
  2140. \t\t\t\tvar r = item.row;
  2141. \t\t\t\t// 幅 / 高さは数値入力 (mm) が来るので \"1750mm\" 形式で保存する.
  2142. \t\t\t\t// 古い radio 由来の \"200cm まで\" 形式が来た場合はそのまま保存して互換.
  2143. \t\t\t\tvar w_mm = parseMm(r.pw);
  2144. \t\t\t\tvar h_mm = parseMm(r.ph);
  2145. \t\t\t\tvar w_save = (w_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.pw))) ? (w_mm + 'mm') : r.pw;
  2146. \t\t\t\tvar h_save = (h_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.ph))) ? (h_mm + 'mm') : r.ph;
  2147. \t\t\t\treturn {
  2148. \t\t\t\t\tsubtype:        r.subtype,
  2149. \t\t\t\t\tw:              w_save,
  2150. \t\t\t\t\th:              h_save,
  2151. \t\t\t\t\tglass:          r.pm,
  2152. \t\t\t\t\tcolor:          r.pc,
  2153. \t\t\t\t\tsetqty:         r.setqty,
  2154. \t\t\t\t\tunit_price_inc: Math.round(r.unit_price_exc * (1 + TAX_RATE)),
  2155. \t\t\t\t\tline_total_inc: Math.round(r.unit_price_exc * r.setqty * (1 + TAX_RATE)),
  2156. \t\t\t\t\tsize_class:     r.size_class,
  2157. \t\t\t\t\tglass_perf:     r.glass_perf,
  2158. \t\t\t\t\tsubsidy_unit:   r.subsidy,
  2159. \t\t\t\t\tsubsidy_total:  r.subsidy * r.setqty
  2160. \t\t\t\t};
  2161. \t\t\t});
  2162. \t\t\tvar opCalc2 = collectOptions();
  2163. \t\t\tvar mitsumori_json = {
  2164. \t\t\t\t\"mitsumori_goukei\": goukeiInc.toLocaleString() + '円',
  2165. \t\t\t\t\"mitsumori_price\":  sumPriceInc.toLocaleString() + '円',
  2166. \t\t\t\t\"mitsumori_ct\":     ctInc.toLocaleString() + '円',
  2167. \t\t\t\t\"mitsumori_option\": optInc.toLocaleString() + '円',
  2168. \t\t\t\t\"mitsumori_off\":    (subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円',
  2169. \t\t\t\t\"maker_price\":      '---円',
  2170. \t\t\t\t\"product_id\":       ";
  2171.         // line 2025
  2172.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2025$this->source); })()), "id", [], "any"falsefalsefalse2025), "html"nulltrue);
  2173.         echo ",
  2174. \t\t\t\t\"sale_type\":        SALE_TYPE_ID,
  2175. \t\t\t\t\"housing_key\":      getCurrentHousingKey(),
  2176. \t\t\t\t\"series_key\":       DETECTED_SERIES,
  2177. \t\t\t\t\"series_grade_cap\": (SERIES_GRADE_CAP_VAL === undefined) ? null : SERIES_GRADE_CAP_VAL,
  2178. \t\t\t\t\"product_grade_cap\":(PRODUCT_GRADE_CAP    === undefined) ? null : PRODUCT_GRADE_CAP,
  2179. \t\t\t\t\"window_types\":     window_types,
  2180. \t\t\t\t\"subsidy_total\":    subsidyAmt,
  2181. \t\t\t\t\"subsidy_raw\":      subsidyRawSum,
  2182. \t\t\t\t\"subsidy_eligible\": subsidyEligible,
  2183. \t\t\t\t\"subsidy_note\":     subsidyNote,
  2184. \t\t\t\t\"op_items\":         opCalc2.items
  2185. \t\t\t};
  2186. \t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  2187. \t\t\trenderWindowTypesModalRows(window_types, subsidyAmt);
  2188. \t\t}
  2189. \t\t/**
  2190. \t\t * sale_type=2 用: 見積モーダル明細テーブルを window_types で動的展開.
  2191. \t\t * - 既存の商品名行 (1 行目) は hide() し、各タイプ行を上に挿入
  2192. \t\t * - 基本工事費行はそのまま (#mitsumori_ct_01 / _02 が更新されている)
  2193. \t\t * - 補助金 (割引額) 行を末尾に追加
  2194. \t\t * - 既存の renderOptionDetailRows と共存できるよう class で区別
  2195. \t\t */
  2196. \t\tfunction renderWindowTypesModalRows(window_types, subsidyAmt) {
  2197. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  2198. \t\t\tif (!\$tbody.length) return;
  2199. \t\t\t// 既存の動的行を全削除 (opt-row は既存実装、wt-row / wt-subsidy-row は今回追加)
  2200. \t\t\t\$tbody.find('tr.wt-row, tr.wt-subsidy-row').remove();
  2201. \t\t\tvar \$itemRow = \$tbody.find('tr').first();
  2202. \t\t\tvar fmt = new Intl.NumberFormat('ja-JP');
  2203. \t\t\tif (!window_types || window_types.length === 0) {
  2204. \t\t\t\t// 集計対象なし → 商品名行を表示に戻す
  2205. \t\t\t\t\$itemRow.show();
  2206. \t\t\t\treturn;
  2207. \t\t\t}
  2208. \t\t\twindow_types.forEach(function(wt, i) {
  2209. \t\t\t\tvar label = '窓タイプ' + (i + 1) + ':'
  2210. \t\t\t\t\t+ (wt.subtype || '') + ' / '
  2211. \t\t\t\t\t+ (wt.w || '') + '×' + (wt.h || '') + ' / '
  2212. \t\t\t\t\t+ (wt.glass || '') + ' / '
  2213. \t\t\t\t\t+ (wt.color || '');
  2214. \t\t\t\tvar \$tr = \$('<tr class=\"wt-row\"></tr>')
  2215. \t\t\t\t\t.append('<td>' + label + '</td>')
  2216. \t\t\t\t\t.append('<td>' + wt.setqty + '</td>')
  2217. \t\t\t\t\t.append('<td>セット</td>')
  2218. \t\t\t\t\t.append('<td>' + fmt.format(wt.unit_price_inc) + '円</td>')
  2219. \t\t\t\t\t.append('<td>' + fmt.format(wt.line_total_inc) + '円</td>');
  2220. \t\t\t\t\$itemRow.before(\$tr);
  2221. \t\t\t});
  2222. \t\t\t// 元の商品名行は複数タイプに置換されたので非表示
  2223. \t\t\t\$itemRow.hide();
  2224. \t\t\t// 補助金(割引額)行を末尾に追加
  2225. \t\t\tif (subsidyAmt > 0) {
  2226. \t\t\t\tvar \$subRow = \$('<tr class=\"wt-subsidy-row\"></tr>')
  2227. \t\t\t\t\t.append('<td>補助金(割引額)</td>')
  2228. \t\t\t\t\t.append('<td>1</td>')
  2229. \t\t\t\t\t.append('<td>式</td>')
  2230. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>')
  2231. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>');
  2232. \t\t\t\t\$tbody.append(\$subRow);
  2233. \t\t\t}
  2234. \t\t}
  2235. \t\t// 公開: onWindowTypeAxisChange (UI 骨格 task 1) からも呼ばれる
  2236. \t\twindow.recalcAll = recalcAllForSaleType2;
  2237. \t\t// 公開: ガラス選択肢が補助金対象か (窓タイプブロック生成時のバッジ判定に使う).
  2238. \t\t// subtype は P→S に落とすことはあっても null にはしないため、性能区分の
  2239. \t\t// 対象/対象外は subtype に依存しない。ここでは series/product 上限のみ適用し、
  2240. \t\t// finalizeGlassGrade が null でなければ「補助金対象ガラス」と判定する。
  2241. \t\twindow.glassYieldsSubsidy = function(glassName) {
  2242. \t\t\tif (!glassName) return false;
  2243. \t\t\treturn finalizeGlassGrade(detectGlassPerformance(glassName), '') !== null;
  2244. \t\t};
  2245. \t\tfunction mitsumori_simulation(type , value_id){
  2246. \t\t\t// sale_type=2 (補助金窓) は複数タイプ集計 UI に統合済み. 既存 mitsumori_simulation は使わない.
  2247. \t\t\tif (typeof SALE_TYPE_ID !== 'undefined' && SALE_TYPE_ID == 2) {
  2248. \t\t\t\t// type/value_id が op\\d+ (施工オプション) の場合はグローバル変数を先に更新
  2249. \t\t\t\tif (type && /^op\\d+\$/.test(type) && value_id) {
  2250. \t\t\t\t\tvar v = \$('#'+value_id).val();
  2251. \t\t\t\t\tif (type === 'op0')  op0  = v;
  2252. \t\t\t\t\tif (type === 'op1')  op1  = v;
  2253. \t\t\t\t\tif (type === 'op2')  op2  = v;
  2254. \t\t\t\t\tif (type === 'op3')  op3  = v;
  2255. \t\t\t\t\tif (type === 'op4')  op4  = v;
  2256. \t\t\t\t\tif (type === 'op5')  op5  = v;
  2257. \t\t\t\t\tif (type === 'op6')  op6  = v;
  2258. \t\t\t\t\tif (type === 'op7')  op7  = v;
  2259. \t\t\t\t\tif (type === 'op8')  op8  = v;
  2260. \t\t\t\t\tif (type === 'op9')  op9  = v;
  2261. \t\t\t\t\tif (type === 'op10') op10 = v;
  2262. \t\t\t\t}
  2263. \t\t\t\trecalcAllForSaleType2();
  2264. \t\t\t\treturn;
  2265. \t\t\t}
  2266. \t\t\t// 価格データ未登録 (pp 行 0 件) の商品は axis 入力に依存せず
  2267. \t\t\t// 「価格データ準備中」を表示して終了する.
  2268. \t\t\t// (例: scrape 未対象の新規商品 — um のウチリモ 7487/7488 等)
  2269. \t\t\tif (!pp || pp.length === 0) {
  2270. \t\t\t\t\$('#mitsumori_message').text(\"価格データ準備中\");
  2271. \t\t\t\t\$('#mitsumori_btn').hide();
  2272. \t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2273. \t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2274. \t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2275. \t\t\t\t\$('#maker_price').text(\"---円\");
  2276. \t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2277. \t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2278. \t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  2279. \t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  2280. \t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  2281. \t\t\t\treturn;
  2282. \t\t\t}
  2283. \t\t\tif(type == \"pw\"){
  2284. \t\t\t\tpw = \$('#'+value_id).val();
  2285. \t\t\t}
  2286. \t\t\tif(type == \"pd\"){
  2287. \t\t\t\tpd = \$('#'+value_id).val();
  2288. \t\t\t}
  2289. \t\t\tif(type == \"ph\"){
  2290. \t\t\t\tph = \$('#'+value_id).val();
  2291. \t\t\t}
  2292. \t\t\tif(type == \"pm\"){
  2293. \t\t\t\tpm = \$('#'+value_id).val();
  2294. \t\t\t}
  2295. \t\t\tif(type == \"pc\"){
  2296. \t\t\t\tpc = \$('#'+value_id).val();
  2297. \t\t\t}
  2298. \t\t\tif(type == \"option1\"){
  2299. \t\t\t\toption1 = \$('#'+value_id).val();
  2300. \t\t\t}
  2301. \t\t\tif(type == \"option2\"){
  2302. \t\t\t\toption2 = \$('#'+value_id).val();
  2303. \t\t\t}
  2304. \t\t\tif(type == \"op0\"){ op0 = \$('#'+value_id).val(); }
  2305. \t\t\tif(type == \"op1\"){ op1 = \$('#'+value_id).val(); }
  2306. \t\t\tif(type == \"op2\"){ op2 = \$('#'+value_id).val(); }
  2307. \t\t\tif(type == \"op3\"){ op3 = \$('#'+value_id).val(); }
  2308. \t\t\tif(type == \"op4\"){ op4 = \$('#'+value_id).val(); }
  2309. \t\t\tif(type == \"op5\"){ op5 = \$('#'+value_id).val(); }
  2310. \t\t\tif(type == \"op6\"){ op6 = \$('#'+value_id).val(); }
  2311. \t\t\tif(type == \"op7\"){ op7 = \$('#'+value_id).val(); }
  2312. \t\t\tif(type == \"op8\"){ op8 = \$('#'+value_id).val(); }
  2313. \t\t\tif(type == \"op9\"){ op9 = \$('#'+value_id).val(); }
  2314. \t\t\tif(type == \"op10\"){ op10 = \$('#'+value_id).val(); }
  2315. \t\t\t// op0 が「商品購入のみ」のとき、他のオプション (op1..op10) を disable 化.
  2316. \t\t\t// 価格計算側 (calcGoukei の purchaseOnly 分岐) は既にゼロ化しているが、
  2317. \t\t\t// UI で選択可能に見えるとユーザーが混乱するため radio を完全に無効化する.
  2318. \t\t\t(function applyPurchaseOnlyUI() {
  2319. \t\t\t\tvar isPurchaseOnly = (op0 === '商品購入のみ');
  2320. \t\t\t\tfor (var k = 1; k <= 10; k++) {
  2321. \t\t\t\t\tvar \$inputs = \$('input[name=\"op' + k + '\"]');
  2322. \t\t\t\t\tif (\$inputs.length === 0) continue;
  2323. \t\t\t\t\t\$inputs.prop('disabled', isPurchaseOnly);
  2324. \t\t\t\t\tvar \$group = \$inputs.first().closest('.form-group');
  2325. \t\t\t\t\t\$group.css({
  2326. \t\t\t\t\t\t'opacity':        isPurchaseOnly ? '0.4'  : '1',
  2327. \t\t\t\t\t\t'pointer-events': isPurchaseOnly ? 'none' : 'auto'
  2328. \t\t\t\t\t});
  2329. \t\t\t\t}
  2330. \t\t\t})();
  2331. \t\t\t// 全 type 共通: 該当 radio を checked にし、ボタンの is-selected を付け替え + ラベル更新.
  2332. \t\t\t//   value_id が指定されていて、対応する DOM 要素が opt-btn 配下にあれば適用する.
  2333. \t\t\t//   (icheck-danger 形式から opt-btn 形式に統一した際、option1/option2/pw/pd/ph/pm/pc 等の
  2334. \t\t\t//    クリックで is-selected が更新されない不具合があったため、op\\d+ 限定の処理を一般化)
  2335. \t\t\tif (value_id) {
  2336. \t\t\t\tvar \$clicked = \$('#' + value_id);
  2337. \t\t\t\tif (\$clicked.length && \$clicked.closest('.opt-btn').length) {
  2338. \t\t\t\t\t\$clicked.prop('checked', true);
  2339. \t\t\t\t\tvar groupName = \$clicked.attr('name');
  2340. \t\t\t\t\t\$('input[name=\"' + groupName + '\"]').closest('.opt-btn').removeClass('is-selected');
  2341. \t\t\t\t\t\$clicked.closest('.opt-btn').addClass('is-selected');
  2342. \t\t\t\t\tvar \$group = \$clicked.closest('.form-group');
  2343. \t\t\t\t\tvar \$label = \$group.find('.rp-section-label');
  2344. \t\t\t\t\tif (\$label.length) {
  2345. \t\t\t\t\t\tvar labelText = \$label.text().split(':')[0].trim();
  2346. \t\t\t\t\t\t\$label.html(labelText + ': <span>' + \$clicked.val() + '</span>');
  2347. \t\t\t\t\t}
  2348. \t\t\t\t\t// op_data の price=0 & 解体/撤去/設置場所 オプションの場合、ON 選択時に「現場調査後に正式お見積もり」文言を表示.
  2349. \t\t\t\t\t//   (twig 側で is_removal_unknown ブロックを描画済み。display 切替のみ JS で行う)
  2350. \t\t\t\t\tif (/^op\\d+\$/.test(type)) {
  2351. \t\t\t\t\t\tvar opIdx = type.replace('op', '');
  2352. \t\t\t\t\t\tvar opEntry = op_data[parseInt(opIdx)];
  2353. \t\t\t\t\t\tif (opEntry) {
  2354. \t\t\t\t\t\t\tvar \$note = \$group.find('.opt-survey-note[data-op-idx=\"' + opIdx + '\"]');
  2355. \t\t\t\t\t\t\tif (\$note.length) {
  2356. \t\t\t\t\t\t\t\tvar isOn = (\$clicked.val() === opEntry.on);
  2357. \t\t\t\t\t\t\t\t\$note.toggle(isOn);
  2358. \t\t\t\t\t\t\t}
  2359. \t\t\t\t\t\t}
  2360. \t\t\t\t\t\t// wd (sale_type=5) のステップ / デッキフェンス用の注記もここで切替.
  2361. \t\t\t\t\t\t//   ステップ → deck_step (op0 だが op_data 範囲外), 必要 選択時に表示.
  2362. \t\t\t\t\t\tvar radioName = \$clicked.attr('name');
  2363. \t\t\t\t\t\tif (radioName === 'deck_step') {
  2364. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-step').toggle(\$clicked.val() === '必要');
  2365. \t\t\t\t\t\t} else if (radioName === 'deck_fence') {
  2366. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-fence').toggle(\$clicked.val() === '必要');
  2367. \t\t\t\t\t\t}
  2368. \t\t\t\t\t}
  2369. \t\t\t\t}
  2370. \t\t\t}
  2371. \t\t\t// 必須項目チェックは sale_type 1 系(カーポート/物置/フェンスなど価格マトリクス必要)に限定
  2372. \t\t\tvar requireMatrix = (SALE_TYPE_ID == 1 || SALE_TYPE_ID == 2 || SALE_TYPE_ID == 3 || SALE_TYPE_ID == 4 || SALE_TYPE_ID == 5 || SALE_TYPE_ID == 6 || SALE_TYPE_ID == 7 || SALE_TYPE_ID == 9);
  2373. \t\t\t// sale_type=3 (物置・ゴミステーション・照明 等) では「素材」を選択肢として扱わない.
  2374. \t\t\t//   - mo/gs/sy は m が \"指定なし\" など名目的にしか入っていない
  2375. \t\t\t//   - sl は m が空のままで matrix に行が来る
  2376. \t\t\t//   そのため pm の必須チェックを sale_type=3 でスキップする。
  2377. \t\t\tvar pmRequired = (SALE_TYPE_ID != 3);
  2378. \t\t\tif (requireMatrix) {
  2379. \t\t\t\tif(pmRequired && pm == \"\"){
  2380. \t\t\t\t\t\$('#mitsumori_message').text(\"素材を選択してください\");
  2381. \t\t\t\t}
  2382. \t\t\t\tif(ph == \"\"){
  2383. \t\t\t\t\t\$('#mitsumori_message').text(\"高さを選択してください\");
  2384. \t\t\t\t}
  2385. \t\t\t\tif(pd == \"\"){
  2386. \t\t\t\t\t\$('#mitsumori_message').text(\"奥行きを選択してください\");
  2387. \t\t\t\t}
  2388. \t\t\t\tif(pw == \"\"){
  2389. \t\t\t\t\t\$('#mitsumori_message').text(\"幅を選択してください\");
  2390. \t\t\t\t}
  2391. \t\t\t\tif(pc == \"\"){
  2392. \t\t\t\t\t\$('#mitsumori_message').text(\"カラーを選択してください\");
  2393. \t\t\t\t\t\$('#mitsumori_btn').hide();
  2394. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2395. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2396. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2397. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  2398. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2399. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2400. \t\t\t\t}
  2401. \t\t\t}
  2402. \t\t\tif(pw != \"\" && pd != \"\" && ph != \"\" && (!pmRequired || pm != \"\") && pc != \"\"){
  2403. \t\t\t\t\$('#mitsumori_btn').show();
  2404. \t\t\t\t// 入力コンテキスト(sale_type 別パラメータ)
  2405. \t\t\t\tvar ctx = {
  2406. \t\t\t\t\tset_count:    parseInt(\$('#set_count').val())    || 1,
  2407. \t\t\t\t\tdaisu:        parseInt(\$('#daisu').val())        || 1,
  2408. \t\t\t\t\tmaisu:        parseInt(\$('#maisu').val())        || 3,
  2409. \t\t\t\t\tsuuryou:      parseInt(\$('#suuryou').val())      || 1,
  2410. \t\t\t\t\tarea:         (function(){
  2411. \t\t\t\t\t\t// tf(人工芝): 施工サイズ 縦(m)×横(m) から面積を算出し #area に反映.
  2412. \t\t\t\t\t\tvar L = parseFloat(\$('#tf_len').val()) || 0;
  2413. \t\t\t\t\t\tvar W = parseFloat(\$('#tf_wid').val()) || 0;
  2414. \t\t\t\t\t\tif (L > 0 && W > 0) { var a = L * W; \$('#area').val(a); return a; }
  2415. \t\t\t\t\t\treturn parseFloat(\$('#area').val()) || 0;
  2416. \t\t\t\t\t})(),
  2417. \t\t\t\t\ttf_len:       parseFloat(\$('#tf_len').val())     || 0,
  2418. \t\t\t\t\ttf_wid:       parseFloat(\$('#tf_wid').val())     || 0,
  2419. \t\t\t\t\ttf_qty:       parseInt(\$('#tf_qty').val())       || 1,
  2420. \t\t\t\t\tquantityOnly: parseInt(\$('#quantity_only').val())|| 1,
  2421. \t\t\t\t\tmado_w:       \$('#mado_w').val() || '',
  2422. \t\t\t\t\tmado_h:       \$('#mado_h').val() || '',
  2423. \t\t\t\t\tmado_type:    \$('input[name=mado_type]:checked').val()  || '',
  2424. \t\t\t\t\tglass_type:   \$('input[name=glass_type]:checked').val() || '',
  2425. \t\t\t\t\tdeck_step:    \$('input[name=deck_step]:checked').val()  || '',
  2426. \t\t\t\t\tdeck_fence:   \$('input[name=deck_fence]:checked').val() || '',
  2427. \t\t\t\t};
  2428. \t\t\t\t// 施工オプション集計(残土処理を含む)
  2429. \t\t\t\tvar opCalc = collectOptions();
  2430. \t\t\t\tvar pp_matched = false;
  2431. \t\t\t\t// 各軸の汎用 axisMatch:
  2432. \t\t\t\t//   user 選択 == matrix 値 / user \"指定なし\" / matrix 値が空
  2433. \t\t\t\tvar axisMatch = function(input, value){
  2434. \t\t\t\t    return input == value || input == \"指定なし\" || value === \"\" || value == null;
  2435. \t\t\t\t};
  2436. \t\t\t\t// 色専用マッチャー: scraper のデータ形式に合わせて拡張する
  2437. \t\t\t\t//   1. 完全一致 / \"指定なし\" / 値が空 → 真 (axisMatch と同じ)
  2438. \t\t\t\t//   2. matrix 値が \"色1/色2/色3\" の形 (同価格グループ) → split して user 選択が含まれれば真
  2439. \t\t\t\t// scraper のロジック (scraper_price.py L765-779):
  2440. \t\t\t\t//   全色同価格 → c=\"\"、価格違いグループあり → 各 group を \"/\" 結合した色名で 1 行
  2441. \t\t\t\tvar colorMatch = function(input, value){
  2442. \t\t\t\t    if (axisMatch(input, value)) return true;
  2443. \t\t\t\t    if (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  2444. \t\t\t\t        var parts = value.split('/');
  2445. \t\t\t\t        for (var idx = 0; idx < parts.length; idx++) {
  2446. \t\t\t\t            if (parts[idx].trim() === input) return true;
  2447. \t\t\t\t        }
  2448. \t\t\t\t    }
  2449. \t\t\t\t    return false;
  2450. \t\t\t\t};
  2451. \t\t\t\t// 他軸 (w/d/h/m + option1/option2) でマッチする pp 行を抽出.
  2452. \t\t\t\t// option1/option2 は um の subtype 等で使われる. axisMatch は free_area 側が
  2453. \t\t\t\t// 空のとき真を返すので、um 以外のカテゴリ (option 軸を使わない) でも影響なし.
  2454. \t\t\t\tvar candidates = pp.filter(function(el){
  2455. \t\t\t\t    return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m)
  2456. \t\t\t\t        && axisMatch(option1, el.option1) && axisMatch(option2, el.option2);
  2457. \t\t\t\t});
  2458. \t\t\t\t// フォールバック: 全軸一致が 0 件のときに限り option1/option2 を無視して再マッチ。
  2459. \t\t\t\t// 玄関ドア等で option1(なし/ランマ付き)・option2(◯◯タイプ) が pm(開き方) から
  2460. \t\t\t\t// 導出可能な冗長軸で、未選択だと全軸 AND 一致を満たせず価格が出ない事象の救済。
  2461. \t\t\t\t// pm/幅/奥行/高さ は従来どおり一致を要求するため通常商品の価格選択に影響しない。
  2462. \t\t\t\tif (candidates.length === 0) {
  2463. \t\t\t\t    candidates = pp.filter(function(el){
  2464. \t\t\t\t        return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m);
  2465. \t\t\t\t    });
  2466. \t\t\t\t}
  2467. \t\t\t\tvar picked = null;
  2468. \t\t\t\t// 優先 1: 色も含めて完全一致 (\"色1/色2\" 形式の split match を含む)
  2469. \t\t\t\tfor (var ii = 0; ii < candidates.length; ii++) {
  2470. \t\t\t\t    if (colorMatch(pc, candidates[ii].c)) { picked = candidates[ii]; break; }
  2471. \t\t\t\t}
  2472. \t\t\t\t// 優先 2: 完全一致なし & user の pc が候補のどの c 値にも該当しない (= 命名違い等)
  2473. \t\t\t\t//   かつ候補全行で price が一致する場合は、色軸を実質無視して先頭行を採用.
  2474. \t\t\t\t//   例 id=3353: pp.c は \"ステンカラー+...\" 6種だが price は全て同じなので
  2475. \t\t\t\t//     SM(スミ) を選んでも安全に最初の行の価格を返せる.
  2476. \t\t\t\tif (!picked && candidates.length > 0) {
  2477. \t\t\t\t    var ppCsInCand = candidates.map(function(r){ return r.c || ''; });
  2478. \t\t\t\t    var pcAbsent = (pc !== '' && pc !== '指定なし' && ppCsInCand.indexOf(pc) === -1
  2479. \t\t\t\t                    && ppCsInCand.every(function(v){ return v.indexOf('/') === -1 || v.split('/').map(function(s){return s.trim();}).indexOf(pc) === -1; }));
  2480. \t\t\t\t    if (pcAbsent) {
  2481. \t\t\t\t        var uniqPrices = new Set();
  2482. \t\t\t\t        candidates.forEach(function(r){ uniqPrices.add(String(r.price)); });
  2483. \t\t\t\t        if (uniqPrices.size === 1) {
  2484. \t\t\t\t            // 全候補同価格 → 色軸を wildcard 扱いで OK
  2485. \t\t\t\t            picked = candidates[0];
  2486. \t\t\t\t        }
  2487. \t\t\t\t        // 価格が異なる場合は意図的に picked=null のまま「対応しておりません」.
  2488. \t\t\t\t    }
  2489. \t\t\t\t}
  2490. \t\t\t\tpp.forEach((el) => {
  2491. \t\t\t\t  if (el === picked) {
  2492. \t\t\t\t\tpp_matched = true;
  2493. \t\t\t\t\t// tg block-keyed オプション差額を集計 (tg 以外は total=0)
  2494. \t\t\t\t\tvar oiCalc = collectOptionItems(el.w || '', el.d || '');
  2495. \t\t\t\t\t// tg ブロックに合わせてラジオを再描画 (tg 以外は no-op)
  2496. \t\t\t\t\trenderOptionItemRadios(el.w || '', el.d || '');
  2497. \t\t\t\t\t// fe ブロックの種類×段数 サブ radio (fe 以外/未設定は no-op)
  2498. \t\t\t\t\trenderFeBlockRadios();
  2499. \t\t\t\t\t// fe ご希望のフェンス設置方法 — 「既存ブロックに穴空け」 entry の連動表示
  2500. \t\t\t\t\tupdateFeOpConditionalVisibility();
  2501. \t\t\t\t\tvar calc       = calcGoukei(el, opCalc.total, ctx);
  2502. \t\t\t\t\tvar goukei     = calc.goukei;
  2503. \t\t\t\t\tvar price      = calc.price;
  2504. \t\t\t\t\tvar ct         = calc.ct;
  2505. \t\t\t\t\tvar optionSum  = calc.opt;
  2506. \t\t\t\t\t// tf(人工芝): 必要枚数入力へ算出結果を反映(施工サイズ入力時は上書き、
  2507. \t\t\t\t\t// 直接指定時は同値なので実質変化なし。要素が無い sale_type では no-op)
  2508. \t\t\t\t\tvar \$tfQty = \$('#tf_qty');
  2509. \t\t\t\t\tif (\$tfQty.length) \$tfQty.val(calc.qty || 1);
  2510. \t\t\t\t\t// オプション差額は税抜 → 税込に変換して合計に加算
  2511. \t\t\t\t\tvar oiIncTax   = toIncTax(oiCalc.total);
  2512. \t\t\t\t\tgoukei += oiIncTax;
  2513. \t\t\t\t\tprice  += oiIncTax;  // 差額は本体価格扱いとして mitsumori_price にも加算
  2514. \t\t\t\t\t// maker_price も scraper が税抜で保存しているため税込に変換
  2515. \t\t\t\tvar makerPrice = toIncTax(parseInt(el.maker_price) || 0);
  2516. \t\t\t\t\t\$('#mitsumori_message').text(formatter.format(goukei) + \"円\");
  2517. \t\t\t\t\t\$('#mitsumori_goukei').text(formatter.format(goukei) + \"円\");
  2518. \t\t\t\t\t\$('#mitsumori_off').text(formatter.format(price - makerPrice) + \"円\");
  2519. \t\t\t\t\t\$('#mitsumori_price').text(formatter.format(price) + \"円\");
  2520. \t\t\t\t\t\$('#maker_price').text(formatter.format(makerPrice) + \"円\");
  2521. \t\t\t\t\t\$('#mitsumori_ct').text(formatter.format(ct) + \"円\");
  2522. \t\t\t\t\t\$('#mitsumori_option').text(formatter.format(optionSum) + \"円\");
  2523. \t\t\t\t\t\$('#mitsumori_kei').text(formatter.format(goukei) + \"円\");
  2524. \t\t\t\t\t\$('#mitsumori_price_01').text(formatter.format(price) + \"円\");
  2525. \t\t\t\t\t\$('#mitsumori_price_02').text(formatter.format(price) + \"円\");
  2526. \t\t\t\t\t\$('#mitsumori_ct_01').text(formatter.format(ct) + \"円\");
  2527. \t\t\t\t\t\$('#mitsumori_ct_02').text(formatter.format(ct) + \"円\");
  2528. \t\t\t\t\t\$('#mitsumori_goukei_02').text(formatter.format(goukei) + \"円\");
  2529. \t\t\t\t\tvar shoukei = goukei / 1.1;
  2530. \t\t\t\t\tvar tax     = parseInt(goukei - shoukei);
  2531. \t\t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(parseInt(shoukei)) + \"円\");
  2532. \t\t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + \"円\");
  2533. \t\t\t\t\t// PDF 明細用:オプション内訳テーブルを差し込む (施工オプション + tg block オプション)
  2534. \t\t\t\t\trenderOptionDetailRows(opCalc.items.concat(oiCalc.items.map(function(it){
  2535. \t\t\t\t\t\treturn { name: it.name, value: it.label, price: it.diff };
  2536. \t\t\t\t\t})));
  2537. \t\t\t\t  }
  2538. \t\t\t\t});
  2539. \t\t\t\tif (!pp_matched) {
  2540. \t\t\t\t\t\$('#mitsumori_message').text(\"この組み合わせは対応しておりません\");
  2541. \t\t\t\t\t\$('#mitsumori_btn').hide();
  2542. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  2543. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  2544. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  2545. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  2546. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  2547. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  2548. \t\t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  2549. \t\t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  2550. \t\t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  2551. \t\t\t\t}
  2552. \t\t\t\t// mitsumori_json: バック側に送信する見積データ
  2553. \t\t\t\tvar mitsumori_json = { \"mitsumori_goukei\": \$('#mitsumori_goukei').text(),
  2554. \t\t\t\t\t\t\t\t\t\t\"mitsumori_goukei_02\": \$('#mitsumori_goukei_02').text(),
  2555. \t\t\t\t\t\t\t\t\t\t\"mitsumori_price\": \$('#mitsumori_price').text(),
  2556. \t\t\t\t\t\t\t\t\t\t\"maker_price\": \$('#maker_price').text(),
  2557. \t\t\t\t\t\t\t\t\t\t\"mitsumori_off\": \$('#mitsumori_off').text(),
  2558. \t\t\t\t\t\t\t\t\t\t\"mitsumori_ct\": \$('#mitsumori_ct').text(),
  2559. \t\t\t\t\t\t\t\t\t\t\"mitsumori_option\": \$('#mitsumori_option').text(),
  2560. \t\t\t\t\t\t\t\t\t\t\"product_id\": ";
  2561.         // line 2442
  2562.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2442$this->source); })()), "id", [], "any"falsefalsefalse2442), "html"nulltrue);
  2563.         echo ",
  2564. \t\t\t\t\t\t\t\t\t\t\"sale_type\": SALE_TYPE_ID,
  2565. \t\t\t\t\t\t\t\t\t\t\"pw\": pw,
  2566. \t\t\t\t\t\t\t\t\t\t\"pd\": pd,
  2567. \t\t\t\t\t\t\t\t\t\t\"ph\": ph,
  2568. \t\t\t\t\t\t\t\t\t\t\"pm\": pm,
  2569. \t\t\t\t\t\t\t\t\t\t\"pc\": pc,
  2570. \t\t\t\t\t\t\t\t\t\t\"op\": [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10],
  2571. \t\t\t\t\t\t\t\t\t\t\"op_items\": opCalc.items,
  2572. \t\t\t\t\t\t\t\t\t\t\"mado_w\":     ctx.mado_w,
  2573. \t\t\t\t\t\t\t\t\t\t\"mado_h\":     ctx.mado_h,
  2574. \t\t\t\t\t\t\t\t\t\t\"mado_type\":  ctx.mado_type,
  2575. \t\t\t\t\t\t\t\t\t\t\"glass_type\": ctx.glass_type,
  2576. \t\t\t\t\t\t\t\t\t\t\"set_count\":  ctx.set_count,
  2577. \t\t\t\t\t\t\t\t\t\t\"daisu\":      ctx.daisu,
  2578. \t\t\t\t\t\t\t\t\t\t\"maisu\":      ctx.maisu,
  2579. \t\t\t\t\t\t\t\t\t\t\"suuryou\":    ctx.suuryou,
  2580. \t\t\t\t\t\t\t\t\t\t\"area\":       ctx.area,
  2581. \t\t\t\t\t\t\t\t\t\t\"tf_len\":     ctx.tf_len,
  2582. \t\t\t\t\t\t\t\t\t\t\"tf_wid\":     ctx.tf_wid,
  2583. \t\t\t\t\t\t\t\t\t\t\"tf_qty\":     \$('#tf_qty').val(),
  2584. \t\t\t\t\t\t\t\t\t\t\"deck_step\":  ctx.deck_step,
  2585. \t\t\t\t\t\t\t\t\t\t\"deck_fence\": ctx.deck_fence };
  2586. \t\t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  2587. \t\t\t}
  2588. \t\t}
  2589. \t\t// PDF/モーダル明細の動的差し替え(基本工事費の次にオプション行を追加)
  2590. \t\tfunction renderOptionDetailRows(items) {
  2591. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  2592. \t\t\tif (!\$tbody.length) return;
  2593. \t\t\t\$tbody.find('tr.opt-row').remove();
  2594. \t\t\tvar anchorRow = \$tbody.find('tr').filter(function(){
  2595. \t\t\t\treturn \$(this).find('td:first').text().indexOf('残土') !== -1
  2596. \t\t\t\t\t|| \$(this).find('td:first').text().indexOf('基本工事費') !== -1;
  2597. \t\t\t}).last();
  2598. \t\t\titems.forEach(function(it){
  2599. \t\t\t\tif (!it.name || !it.value) return;
  2600. \t\t\t\tvar priceTxt = it.price > 0
  2601. \t\t\t\t\t? formatter.format(it.price) + '円'
  2602. \t\t\t\t\t: '0円';
  2603. \t\t\t\tvar \$tr = \$('<tr class=\"opt-row\"></tr>')
  2604. \t\t\t\t\t.append('<td>' + it.name + ':' + it.value + '</td>')
  2605. \t\t\t\t\t.append('<td>1</td>')
  2606. \t\t\t\t\t.append('<td>式</td>')
  2607. \t\t\t\t\t.append('<td>' + priceTxt + '</td>')
  2608. \t\t\t\t\t.append('<td>' + (it.price > 0 ? formatter.format(it.price) + '円' : '') + '</td>');
  2609. \t\t\t\tif (anchorRow.length) {
  2610. \t\t\t\t\tanchorRow.after(\$tr);
  2611. \t\t\t\t\tanchorRow = \$tr;
  2612. \t\t\t\t} else {
  2613. \t\t\t\t\t\$tbody.append(\$tr);
  2614. \t\t\t\t}
  2615. \t\t\t});
  2616. \t\t}
  2617. \t\t// 見積書モーダルを開く直前に、右側「現在のお見積り額」パネルの表示値を
  2618. \t\t// モーダル内の対応 ID にコピーして金額の食い違いを防ぐ。
  2619. \t\t// pw/pd/ph/pm が未選択で mitsumori_simulation の full update に到達しない場合でも、
  2620. \t\t// パネル側の値(HTML 静的初期値 or 直近の simulation 結果)が modal にも反映される。
  2621. \t\tfunction syncMitsumoriModalFromPanel() {
  2622. \t\t\tvar goukeiText = \$('#mitsumori_goukei').text();
  2623. \t\t\tvar priceText  = \$('#mitsumori_price').text();
  2624. \t\t\tvar ctText     = \$('#mitsumori_ct').text();
  2625. \t\t\t\$('#mitsumori_kei').text(goukeiText);
  2626. \t\t\t\$('#mitsumori_price_01').text(priceText);
  2627. \t\t\t\$('#mitsumori_price_02').text(priceText);
  2628. \t\t\t\$('#mitsumori_ct_01').text(ctText);
  2629. \t\t\t\$('#mitsumori_ct_02').text(ctText);
  2630. \t\t\t\$('#mitsumori_goukei_02').text(goukeiText);
  2631. \t\t\t// 小計 / 消費税 は税込 goukei から逆算
  2632. \t\t\tvar num = parseInt(goukeiText.replace(/[^\\d-]/g, ''), 10);
  2633. \t\t\tif (!isNaN(num) && num > 0) {
  2634. \t\t\t\tvar shoukei = Math.round(num / 1.1);
  2635. \t\t\t\tvar tax     = num - shoukei;
  2636. \t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(shoukei) + '円');
  2637. \t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + '円');
  2638. \t\t\t} else {
  2639. \t\t\t\t\$('#mitsumori_shoukei').text('---円');
  2640. \t\t\t\t\$('#mitsumori_tax').text('---円');
  2641. \t\t\t}
  2642. \t\t}
  2643. \t\t\$(document).on('show.bs.modal', '#modal-mitsumori', function () {
  2644. \t\t\tsyncMitsumoriModalFromPanel();
  2645. \t\t});
  2646.         ";
  2647.         // line 2536
  2648.         echo "        ";
  2649.         if (((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2536$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2536$this->source); })())) == 1) || (twig_join_filter((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2536$this->source); })())) == "")))) {
  2650.             // line 2537
  2651.             echo "            pc = \"指定なし\";
  2652.             ";
  2653.             // line 2538
  2654.             $context['_parent'] = $context;
  2655.             $context['_seq'] = twig_ensure_traversable((isset($context["p_c"]) || array_key_exists("p_c"$context) ? $context["p_c"] : (function () { throw new RuntimeError('Variable "p_c" does not exist.'2538$this->source); })()));
  2656.             foreach ($context['_seq'] as $context["_key"] => $context["pc_val"]) {
  2657.                 if ($context["pc_val"]) {
  2658.                     echo " pc = \"";
  2659.                     echo twig_escape_filter($this->env$context["pc_val"], "html"nulltrue);
  2660.                     echo "\"; ";
  2661.                 }
  2662.             }
  2663.             $_parent $context['_parent'];
  2664.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pc_val'], $context['_parent'], $context['loop']);
  2665.             $context array_intersect_key($context$_parent) + $_parent;
  2666.             // line 2539
  2667.             echo "            ";
  2668.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2539$this->source); })()) && (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2539$this->source); })())) == 1))) {
  2669.                 // line 2540
  2670.                 echo "                ";
  2671.                 $context['_parent'] = $context;
  2672.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2540$this->source); })()));
  2673.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  2674.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2540))) {
  2675.                         echo " pc = \"";
  2676.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2540), "html"nulltrue);
  2677.                         echo "\"; ";
  2678.                     }
  2679.                 }
  2680.                 $_parent $context['_parent'];
  2681.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  2682.                 $context array_intersect_key($context$_parent) + $_parent;
  2683.                 // line 2541
  2684.                 echo "            ";
  2685.             }
  2686.             // line 2542
  2687.             echo "        ";
  2688.         } elseif (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2542$this->source); })()) && (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2542$this->source); })())) == 1))) {
  2689.             // line 2543
  2690.             echo "            pc = \"指定なし\";
  2691. \t\t\t";
  2692.             // line 2544
  2693.             $context['_parent'] = $context;
  2694.             $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'2544$this->source); })()));
  2695.             foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  2696.                 if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2544))) {
  2697.                     echo " pc = \"";
  2698.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse2544), "html"nulltrue);
  2699.                     echo "\"; ";
  2700.                 }
  2701.             }
  2702.             $_parent $context['_parent'];
  2703.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  2704.             $context array_intersect_key($context$_parent) + $_parent;
  2705.             // line 2545
  2706.             echo "\t\t";
  2707.         }
  2708.         // line 2546
  2709.         echo "
  2710.         ";
  2711.         // line 2547
  2712.         if (((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2547$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2547$this->source); })())) == 1) || (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2547$this->source); })())) == "")))) {
  2713.             // line 2548
  2714.             echo "            pw = \"指定なし\";
  2715. \t\t\t";
  2716.             // line 2549
  2717.             $context['_parent'] = $context;
  2718.             $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'2549$this->source); })()));
  2719.             foreach ($context['_seq'] as $context["_key"] => $context["pw"]) {
  2720.                 if ($context["pw"]) {
  2721.                     echo " pw = \"";
  2722.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  2723.                     echo "\"; ";
  2724.                 }
  2725.             }
  2726.             $_parent $context['_parent'];
  2727.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw'], $context['_parent'], $context['loop']);
  2728.             $context array_intersect_key($context$_parent) + $_parent;
  2729.             // line 2550
  2730.             echo "\t\t";
  2731.         }
  2732.         // line 2551
  2733.         echo "
  2734.         ";
  2735.         // line 2552
  2736.         if (((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2552$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2552$this->source); })())) == 1) || (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2552$this->source); })())) == "")))) {
  2737.             // line 2553
  2738.             echo "            pd = \"指定なし\";
  2739. \t\t\t";
  2740.             // line 2554
  2741.             $context['_parent'] = $context;
  2742.             $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'2554$this->source); })()));
  2743.             foreach ($context['_seq'] as $context["_key"] => $context["pd"]) {
  2744.                 if ($context["pd"]) {
  2745.                     echo " pd = \"";
  2746.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  2747.                     echo "\"; ";
  2748.                 }
  2749.             }
  2750.             $_parent $context['_parent'];
  2751.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd'], $context['_parent'], $context['loop']);
  2752.             $context array_intersect_key($context$_parent) + $_parent;
  2753.             // line 2555
  2754.             echo "\t\t";
  2755.         }
  2756.         // line 2556
  2757.         echo "
  2758.         ";
  2759.         // line 2557
  2760.         if (((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2557$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2557$this->source); })())) == 1) || (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2557$this->source); })())) == "")))) {
  2761.             // line 2558
  2762.             echo "            ph = \"指定なし\";
  2763. \t\t\t";
  2764.             // line 2559
  2765.             $context['_parent'] = $context;
  2766.             $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'2559$this->source); })()));
  2767.             foreach ($context['_seq'] as $context["_key"] => $context["ph"]) {
  2768.                 if ($context["ph"]) {
  2769.                     echo " ph = \"";
  2770.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  2771.                     echo "\"; ";
  2772.                 }
  2773.             }
  2774.             $_parent $context['_parent'];
  2775.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph'], $context['_parent'], $context['loop']);
  2776.             $context array_intersect_key($context$_parent) + $_parent;
  2777.             // line 2560
  2778.             echo "\t\t";
  2779.         }
  2780.         // line 2561
  2781.         echo "
  2782.         ";
  2783.         // line 2562
  2784.         if (((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2562$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2562$this->source); })())) == 1) || (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2562$this->source); })())) == "")))) {
  2785.             // line 2563
  2786.             echo "            pm = \"指定なし\";
  2787. \t\t\t";
  2788.             // line 2564
  2789.             $context['_parent'] = $context;
  2790.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'2564$this->source); })()));
  2791.             foreach ($context['_seq'] as $context["_key"] => $context["pm"]) {
  2792.                 if ($context["pm"]) {
  2793.                     echo " pm = \"";
  2794.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  2795.                     echo "\"; ";
  2796.                 }
  2797.             }
  2798.             $_parent $context['_parent'];
  2799.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm'], $context['_parent'], $context['loop']);
  2800.             $context array_intersect_key($context$_parent) + $_parent;
  2801.             // line 2565
  2802.             echo "\t\t";
  2803.         }
  2804.         // line 2566
  2805.         echo "
  2806.         ";
  2807.         // line 2568
  2808.         echo "        ";
  2809.         if (((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2568$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2568$this->source); })())) == 1) || (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2568$this->source); })())) == "")))) {
  2810.             // line 2569
  2811.             echo "            option1 = \"\";
  2812. \t\t\t";
  2813.             // line 2570
  2814.             $context['_parent'] = $context;
  2815.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'2570$this->source); })()));
  2816.             foreach ($context['_seq'] as $context["_key"] => $context["opt1"]) {
  2817.                 if ($context["opt1"]) {
  2818.                     echo " option1 = \"";
  2819.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt1"], "js"), "html"nulltrue);
  2820.                     echo "\"; ";
  2821.                 }
  2822.             }
  2823.             $_parent $context['_parent'];
  2824.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1'], $context['_parent'], $context['loop']);
  2825.             $context array_intersect_key($context$_parent) + $_parent;
  2826.             // line 2571
  2827.             echo "\t\t";
  2828.         }
  2829.         // line 2572
  2830.         echo "
  2831.         ";
  2832.         // line 2573
  2833.         if (((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2573$this->source); })()) && ((twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2573$this->source); })())) == 1) || (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2573$this->source); })())) == "")))) {
  2834.             // line 2574
  2835.             echo "            option2 = \"\";
  2836. \t\t\t";
  2837.             // line 2575
  2838.             $context['_parent'] = $context;
  2839.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'2575$this->source); })()));
  2840.             foreach ($context['_seq'] as $context["_key"] => $context["opt2"]) {
  2841.                 if ($context["opt2"]) {
  2842.                     echo " option2 = \"";
  2843.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt2"], "js"), "html"nulltrue);
  2844.                     echo "\"; ";
  2845.                 }
  2846.             }
  2847.             $_parent $context['_parent'];
  2848.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt2'], $context['_parent'], $context['loop']);
  2849.             $context array_intersect_key($context$_parent) + $_parent;
  2850.             // line 2576
  2851.             echo "\t\t";
  2852.         }
  2853.         // line 2577
  2854.         echo "
  2855. \t\t// カラー radio が複数あるとき初期チェックが無いと「カラーを選択してください」固定になるので、
  2856. \t\t// 何もチェックされていなければ「最初の radio」を選択する。
  2857. \t\t// sale_type≠3 は name=\"color\", sale_type=3 は name=\"color3\".
  2858. \t\t//
  2859. \t\t// 注意:
  2860. \t\t//   ・search_word(= radio の値)と pp.c(= matrix の色軸)は別の命名体系のケースがある
  2861. \t\t//     (例 id=3353: radio=\"SM(スミ)\" / pp.c=\"ステンカラー+セピアブラウン\")
  2862. \t\t//   ・pp.c に合わせて radio を選ぼうとしても文字列一致しないので無意味。
  2863. \t\t//   ・単純に「先頭の radio」を選ぶ実装に戻し、マッチング側で命名体系違いを吸収する
  2864. \t\t//     (pc が pp.c のどの値にもマッチしないときは色軸を wildcard 扱いにする)。
  2865. \t\t//   ・.rp-section-label のテキストも忘れずに同期する(古い session 値が残ると
  2866. \t\t//     \"ステンカラー+セピアブラウン\" のような表示と実際の radio が食い違う)。
  2867. \t\t(function autoSelectFirstColor(){
  2868. \t\t\tvar groups = ['color', 'color3'];
  2869. \t\t\tfor (var gi = 0; gi < groups.length; gi++) {
  2870. \t\t\t\tvar name = groups[gi];
  2871. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + name + '\"]');
  2872. \t\t\t\tif (nodes.length === 0) continue;
  2873. \t\t\t\tvar anyChecked = false;
  2874. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  2875. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  2876. \t\t\t\t}
  2877. \t\t\t\tif (anyChecked) continue;
  2878. \t\t\t\tvar target = nodes[0];
  2879. \t\t\t\ttarget.checked = true;
  2880. \t\t\t\tpc = target.value;
  2881. \t\t\t\t// opt-btn の is-selected を付け替え
  2882. \t\t\t\tvar lbl = target.closest('.opt-btn');
  2883. \t\t\t\tif (lbl) {
  2884. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  2885. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  2886. \t\t\t\t\tlbl.classList.add('is-selected');
  2887. \t\t\t\t}
  2888. \t\t\t\t// 「カラー: <name>」表示の同期(古い mitsumori_json.pc が残らないように)
  2889. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  2890. \t\t\t\tif (grp) {
  2891. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  2892. \t\t\t\t\tif (section) {
  2893. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  2894. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  2895. \t\t\t\t\t}
  2896. \t\t\t\t}
  2897. \t\t\t}
  2898. \t\t})();
  2899. \t\t// option1 / option2 / pw / pd / ph / pm (matrix 軸の radio 群) も同様に
  2900. \t\t// 「どれもチェックされていなければ先頭を選ぶ」を適用する.
  2901. \t\t//   sale_type=2 の窓タイプ等で「初期表示時に一番初めの選択肢が選択されていない」事象を解消.
  2902. \t\t(function autoSelectFirstMatrixAxis(){
  2903. \t\t\tvar axes = [
  2904. \t\t\t\t{ name: 'pw',      jsVar: 'pw' },
  2905. \t\t\t\t{ name: 'pd',      jsVar: 'pd' },
  2906. \t\t\t\t{ name: 'ph',      jsVar: 'ph' },
  2907. \t\t\t\t{ name: 'pm',      jsVar: 'pm' },
  2908. \t\t\t\t{ name: 'glass_type', jsVar: 'pm' },
  2909. \t\t\t\t{ name: 'option1', jsVar: 'option1' },
  2910. \t\t\t\t{ name: 'option2', jsVar: 'option2' }
  2911. \t\t\t];
  2912. \t\t\tfor (var ai = 0; ai < axes.length; ai++) {
  2913. \t\t\t\tvar ax = axes[ai];
  2914. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + ax.name + '\"]');
  2915. \t\t\t\tif (nodes.length === 0) continue;
  2916. \t\t\t\tvar anyChecked = false;
  2917. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  2918. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  2919. \t\t\t\t}
  2920. \t\t\t\tif (anyChecked) continue;
  2921. \t\t\t\tvar target = nodes[0];
  2922. \t\t\t\ttarget.checked = true;
  2923. \t\t\t\t// グローバル JS 変数も埋める
  2924. \t\t\t\tif (ax.jsVar === 'pw') pw = target.value;
  2925. \t\t\t\telse if (ax.jsVar === 'pd') pd = target.value;
  2926. \t\t\t\telse if (ax.jsVar === 'ph') ph = target.value;
  2927. \t\t\t\telse if (ax.jsVar === 'pm') pm = target.value;
  2928. \t\t\t\telse if (ax.jsVar === 'option1') option1 = target.value;
  2929. \t\t\t\telse if (ax.jsVar === 'option2') option2 = target.value;
  2930. \t\t\t\tvar lbl = target.closest('.opt-btn');
  2931. \t\t\t\tif (lbl) {
  2932. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  2933. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  2934. \t\t\t\t\tlbl.classList.add('is-selected');
  2935. \t\t\t\t}
  2936. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  2937. \t\t\t\tif (grp) {
  2938. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  2939. \t\t\t\t\tif (section) {
  2940. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  2941. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  2942. \t\t\t\t\t}
  2943. \t\t\t\t}
  2944. \t\t\t}
  2945. \t\t})();
  2946. \t\t// 取付/設置工事トグル(off 値が「商品購入のみ」のオプション)は、新規アクセス時に
  2947. \t\t// どちらの radio も未チェックのため初期価格が「商品購入のみ」= 基本工事費抜きになる。
  2948. \t\t// 顧客要望(#10)に合わせ、未選択時は「工事も希望する」(on 側) を初期選択し、
  2949. \t\t// 初期表示を基本工事費込みの最安値に統一する(色・寸法軸の先頭自動選択と同型)。
  2950. \t\t//   ・判定キーは calcGoukei / applyPurchaseOnlyUI と同じ定数「商品購入のみ」。
  2951. \t\t//   ・別用途で op{n} を流用する商品(ウッドデッキ deck_step 等)は radio 値に
  2952. \t\t//     「商品購入のみ」を含まないため対象外(既存挙動を壊さない)。
  2953. \t\t//   ・mitsumori_json 復元やユーザー操作で既に選択済みなら尊重する。
  2954. \t\t(function autoSelectFirstInstall(){
  2955. \t\t\tfor (var i = 0; i <= 10; i++) {
  2956. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"op' + i + '\"]');
  2957. \t\t\t\tif (nodes.length === 0) continue;
  2958. \t\t\t\t// このグループが「商品購入のみ」を off に持つ工事トグルか判定し、
  2959. \t\t\t\t// 「商品購入のみ」でない側 (= 工事希望 on) を取得する。
  2960. \t\t\t\tvar hasPurchaseOnly = false;
  2961. \t\t\t\tvar onNode = null;
  2962. \t\t\t\tfor (var j = 0; j < nodes.length; j++) {
  2963. \t\t\t\t\tif (nodes[j].value === '商品購入のみ') hasPurchaseOnly = true;
  2964. \t\t\t\t\telse if (!onNode) onNode = nodes[j];
  2965. \t\t\t\t}
  2966. \t\t\t\tif (!hasPurchaseOnly || !onNode) continue;
  2967. \t\t\t\tvar anyChecked = false;
  2968. \t\t\t\tfor (var k = 0; k < nodes.length; k++) {
  2969. \t\t\t\t\tif (nodes[k].checked) { anyChecked = true; break; }
  2970. \t\t\t\t}
  2971. \t\t\t\tif (anyChecked) continue;
  2972. \t\t\t\tonNode.checked = true;
  2973. \t\t\t\t// グローバル op 変数を on 値で埋める(calcGoukei の purchaseOnly 判定が参照)
  2974. \t\t\t\tswitch (i) {
  2975. \t\t\t\t\tcase 0:  op0  = onNode.value; break;
  2976. \t\t\t\t\tcase 1:  op1  = onNode.value; break;
  2977. \t\t\t\t\tcase 2:  op2  = onNode.value; break;
  2978. \t\t\t\t\tcase 3:  op3  = onNode.value; break;
  2979. \t\t\t\t\tcase 4:  op4  = onNode.value; break;
  2980. \t\t\t\t\tcase 5:  op5  = onNode.value; break;
  2981. \t\t\t\t\tcase 6:  op6  = onNode.value; break;
  2982. \t\t\t\t\tcase 7:  op7  = onNode.value; break;
  2983. \t\t\t\t\tcase 8:  op8  = onNode.value; break;
  2984. \t\t\t\t\tcase 9:  op9  = onNode.value; break;
  2985. \t\t\t\t\tcase 10: op10 = onNode.value; break;
  2986. \t\t\t\t}
  2987. \t\t\t\t// opt-btn の is-selected を付け替え
  2988. \t\t\t\tvar lbl = onNode.closest('.opt-btn');
  2989. \t\t\t\tif (lbl) {
  2990. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  2991. \t\t\t\t\tfor (var s = 0; s < sib.length; s++) sib[s].classList.remove('is-selected');
  2992. \t\t\t\t\tlbl.classList.add('is-selected');
  2993. \t\t\t\t}
  2994. \t\t\t\t// rp-section-label 表示同期 + 現地調査文言(is_removal_unknown / is_tf_kouji)を on 表示に
  2995. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || onNode.closest('.form-group');
  2996. \t\t\t\tif (grp) {
  2997. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  2998. \t\t\t\t\tif (section) {
  2999. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  3000. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + onNode.value + '</span>';
  3001. \t\t\t\t\t}
  3002. \t\t\t\t\tvar note = grp.querySelector('.opt-survey-note[data-op-idx=\"' + i + '\"]');
  3003. \t\t\t\t\tif (note) note.style.display = '';
  3004. \t\t\t\t}
  3005. \t\t\t}
  3006. \t\t})();
  3007. \t\t// ページ読み込み時: 見積金額が「合計」になっているため、カート数量は基本1
  3008. \t\t// sale_type=9(商品のみ購入)だけ通常 EC として数量を引き継ぐ
  3009. \t\t(function initQuantityByType(){
  3010. \t\t\tvar saleType = ";
  3011.         // line 2743
  3012.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'2743$this->source); })()), "SaleType", [], "any"falsefalsefalse2743), "id", [], "any"falsefalsefalse2743), "html"nulltrue);
  3013.         echo ";
  3014. \t\t\tif (saleType == 9 && \$('#quantity_only').length) {
  3015. \t\t\t\t\$('#quantity').val(parseInt(\$('#quantity_only').val()) || 1);
  3016. \t\t\t} else {
  3017. \t\t\t\t\$('#quantity').val(1);
  3018. \t\t\t\t\$('input[name=\"quantity\"]').val(1);
  3019. \t\t\t}
  3020. \t\t})();
  3021. \t\t// type → ラベルのプレフィックス文字列
  3022. \t\t// option1/option2 のラベルは category 依存 (rd: ランマ/タイプ, sh: サイズプリセット/駆動方式 等).
  3023. \t\t// PHP から渡された option1_label / option2_label を埋め込み、JS 側でラベル更新に使う.
  3024. \t\tvar optLabelMap = {pc:'カラー', pw:'幅', pd:'奥行き', ph:'高さ', pm:'素材',
  3025. \t\t                   option1: '";
  3026.         // line 2756
  3027.         echo twig_escape_filter($this->envtwig_escape_filter($this->env, ((array_key_exists("option1_label"$context)) ? (_twig_default_filter((isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'2756$this->source); })()), "オプション1")) : ("オプション1")), "js"), "html"nulltrue);
  3028.         echo "',
  3029. \t\t                   option2: '";
  3030.         // line 2757
  3031.         echo twig_escape_filter($this->envtwig_escape_filter($this->env, ((array_key_exists("option2_label"$context)) ? (_twig_default_filter((isset($context["option2_label"]) || array_key_exists("option2_label"$context) ? $context["option2_label"] : (function () { throw new RuntimeError('Variable "option2_label" does not exist.'2757$this->source); })()), "オプション2")) : ("オプション2")), "js"), "html"nulltrue);
  3032.         echo "'};
  3033. \t\t// type → input[name]
  3034. \t\tvar optNameMap  = {pc:'color', pw:'pw', pd:'pd', ph:'ph', pm:'pm',
  3035. \t\t                   option1: 'option1', option2: 'option2'};
  3036. \t\t// opt-btn用: 値を直接受け取るラッパー
  3037. \t\tfunction mitsumori_simulation_val(type, value) {
  3038. \t\t\tif (type === 'pc') pc = value;
  3039. \t\t\tif (type === 'pw') pw = value;
  3040. \t\t\tif (type === 'pd') pd = value;
  3041. \t\t\tif (type === 'ph') ph = value;
  3042. \t\t\tif (type === 'pm') pm = value;
  3043. \t\t\tif (type === 'option1') option1 = value;
  3044. \t\t\tif (type === 'option2') option2 = value;
  3045. \t\t\t// is-selected クラスを同グループ内で付け替え
  3046. \t\t\tvar inputName = optNameMap[type];
  3047. \t\t\tif (inputName) {
  3048. \t\t\t\tvar \$btns = \$('input[name=\"' + inputName + '\"]').closest('.opt-btn');
  3049. \t\t\t\t\$btns.removeClass('is-selected');
  3050. \t\t\t\t\$btns.filter(function(){
  3051. \t\t\t\t\treturn \$(this).find('input').val() === value;
  3052. \t\t\t\t}).addClass('is-selected');
  3053. \t\t\t}
  3054. \t\t\t// ラベル行の選択値テキストを更新(例: 「カラー: ブラック」)
  3055. \t\t\tvar labelPrefix = optLabelMap[type];
  3056. \t\t\tif (labelPrefix) {
  3057. \t\t\t\t// 対象のrp-section-labelを特定(input[name]を含む親を遡る)
  3058. \t\t\t\tvar \$group = \$('input[name=\"' + inputName + '\"]').first().closest('.form-group');
  3059. \t\t\t\tvar \$label = \$group.find('.rp-section-label');
  3060. \t\t\t\t\$label.html(labelPrefix + ': <span>' + value + '</span>');
  3061. \t\t\t}
  3062. \t\t\t// simulation本体を呼ぶ(value_idは空でOK、グローバル変数を使う)
  3063. \t\t\tmitsumori_simulation('', '');
  3064. \t\t}
  3065. \t\tmitsumori_simulation(\"\",\"\");
  3066. \t\t// ボタン群: 親幅を超える、または3行以上になる場合は is-scroll を付与し
  3067. \t\t// 縦3段グリッド+横スクロール表示にする(顧客要望「3列くらいで横スクロール」)
  3068. \t\tfunction applyBtnGroupScroll() {
  3069. \t\t\t\$('.rp-btn-group, .opt-btn-group').each(function() {
  3070. \t\t\t\tvar \$group = \$(this);
  3071. \t\t\t\t\$group.removeClass('is-scroll');
  3072. \t\t\t\tvar \$items = \$group.children();
  3073. \t\t\t\tif (\$items.length === 0) return;
  3074. \t\t\t\tvar parentWidth = \$group.parent().width() || \$group.width();
  3075. \t\t\t\tvar totalWidth = 0;
  3076. \t\t\t\tvar gap = parseInt(\$group.css('gap'), 10) || 8;
  3077. \t\t\t\t\$items.each(function() {
  3078. \t\t\t\t\ttotalWidth += this.offsetWidth + gap;
  3079. \t\t\t\t});
  3080. \t\t\t\t// 単一ボタンが親幅を超える、もしくは合計幅が親幅を超える → 横スクロール化
  3081. \t\t\t\tvar anyTooWide = false;
  3082. \t\t\t\t\$items.each(function() {
  3083. \t\t\t\t\tif (this.offsetWidth > parentWidth) { anyTooWide = true; return false; }
  3084. \t\t\t\t});
  3085. \t\t\t\t// 折り返し時の行数も計測
  3086. \t\t\t\tvar tops = {};
  3087. \t\t\t\t\$items.each(function() { tops[this.offsetTop] = true; });
  3088. \t\t\t\tvar rowCount = Object.keys(tops).length;
  3089. \t\t\t\tif (anyTooWide || totalWidth > parentWidth * 2 || rowCount >= 3) {
  3090. \t\t\t\t\t\$group.addClass('is-scroll');
  3091. \t\t\t\t}
  3092. \t\t\t});
  3093. \t\t}
  3094. \t\tapplyBtnGroupScroll();
  3095. \t\t\$(window).on('resize', function() {
  3096. \t\t\tclearTimeout(window._btnScrollTimer);
  3097. \t\t\twindow._btnScrollTimer = setTimeout(applyBtnGroupScroll, 150);
  3098. \t\t});
  3099. \t\t// onload: 見積金額が確定している場合は「工事費込み価格」表示を一致させる
  3100. \t\t(function syncPrice02Display() {
  3101. \t\t\tvar goukeiEl = document.getElementById('mitsumori_goukei');
  3102. \t\t\tvar displayEl = document.getElementById('price02-display');
  3103. \t\t\tif (!goukeiEl || !displayEl) return;
  3104. \t\t\tvar goukeiText = goukeiEl.textContent.trim();
  3105. \t\t\t// ---円(未確定)の場合は書き換えない
  3106. \t\t\tif (goukeiText && goukeiText !== '---円') {
  3107. \t\t\t\tdisplayEl.textContent = goukeiText;
  3108. \t\t\t}
  3109. \t\t\t// 以降の変更にも追従: mitsumori_goukei を監視
  3110. \t\t\tnew MutationObserver(function() {
  3111. \t\t\t\tvar text = goukeiEl.textContent.trim();
  3112. \t\t\t\tif (text && text !== '---円') {
  3113. \t\t\t\t\tdisplayEl.textContent = text;
  3114. \t\t\t\t}
  3115. \t\t\t}).observe(goukeiEl, { childList: true, subtree: true, characterData: true });
  3116. \t\t})();
  3117. \t\tfunction contact_form(product_id){
  3118. \t\t\t\$('#form1').attr('action', '";
  3119.         // line 2854
  3120.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("contact", ["product" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'2854$this->source); })()), "id", [], "any"falsefalsefalse2854)]), "html"nulltrue);
  3121.         echo "');
  3122. \t\t\t\$('#form1').submit();
  3123. \t\t}
  3124. \t\t// maisu / madoset は下部の新しい関数定義を使用
  3125. \t\tfunction heibei(bei){
  3126. \t\t\t\$('#heibei').val(parseInt(\$('#heibei').val()) + bei);
  3127. \t\t\tif(parseInt(\$('#heibei').val()) < 1){ \$('#heibei').val(1); }
  3128. \t\t\tif(parseInt(\$('#heibei').val()) > 100){ \$('#heibei').val(100); }
  3129. \t\t\t// goukei に既に枚数を含むため、カート数量は1で固定
  3130. \t\t\t\$('#quantity').val(1);
  3131. \t\t\tmitsumori_simulation('heibei','heibei');
  3132. \t\t}
  3133. \t\tfunction daisu(dai){
  3134. \t\t\t\$('#daisu').val(parseInt(\$('#daisu').val()) + dai);
  3135. \t\t\tif(parseInt(\$('#daisu').val()) < 1){ \$('#daisu').val(1); }
  3136. \t\t\tif(parseInt(\$('#daisu').val()) > 10){ \$('#daisu').val(10); }
  3137. \t\t\t\$('#quantity').val(1);
  3138. \t\t\tmitsumori_simulation('daisu','daisu');
  3139. \t\t}
  3140. \t\t// sale_type=7(数量買い・基本工事費固定)用:個数入力
  3141. \t\tfunction suuryou(n){
  3142. \t\t\t\$('#suuryou').val(parseInt(\$('#suuryou').val()) + n);
  3143. \t\t\tif(parseInt(\$('#suuryou').val()) < 1){ \$('#suuryou').val(1); }
  3144. \t\t\tif(parseInt(\$('#suuryou').val()) > 100){ \$('#suuryou').val(100); }
  3145. \t\t\t\$('#quantity').val(1);
  3146. \t\t\tmitsumori_simulation('suuryou','suuryou');
  3147. \t\t}
  3148. \t\tfunction maisu(mai){
  3149. \t\t\t\$('#maisu').val(parseInt(\$('#maisu').val()) + mai);
  3150. \t\t\t// sale_type=4 (フェンス) は3枚未満不可、6 (芝生) は1枚から
  3151. \t\t\tvar minMai = (SALE_TYPE_ID == 4) ? 3 : 1;
  3152. \t\t\tif(parseInt(\$('#maisu').val()) < minMai){ \$('#maisu').val(minMai); }
  3153. \t\t\tif(parseInt(\$('#maisu').val()) > 100){ \$('#maisu').val(100); }
  3154. \t\t\t\$('#quantity').val(1);
  3155. \t\t\tmitsumori_simulation('maisu','maisu');
  3156. \t\t}
  3157. \t\t// タイプ2: セット数プルダウン連動
  3158. \t\tfunction madosetSelect(val){
  3159. \t\t\tvar v = parseInt(val);
  3160. \t\t\tif(v < 1) v = 1;
  3161. \t\t\tif(v > 20) v = 20;
  3162. \t\t\t\$('#set_count').val(v);
  3163. \t\t\t\$('#quantity').val(1);
  3164. \t\t\t\$('input[name=\"quantity\"]').val(1);
  3165. \t\t\tmitsumori_simulation('set','set_count');
  3166. \t\t}
  3167. \t\t// タイプ2: ±ボタン版(後方互換)
  3168. \t\tfunction madoset(mai){
  3169. \t\t\tvar current = parseInt(\$('#set_count').val()) || 1;
  3170. \t\t\tvar next = current + mai;
  3171. \t\t\tif(next < 1) next = 1;
  3172. \t\t\tif(next > 20) next = 20;
  3173. \t\t\t\$('#set_count').val(next);
  3174. \t\t\tmadosetSelect(next);
  3175. \t\t}
  3176. \t\t// タイプ5: ステップ・フェンス選択値を mitsumori_json に保存するためのグローバル変数
  3177. \t\tvar deck_step = \"";
  3178.         // line 2915
  3179.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'2915$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse2915))) {
  3180.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse2915)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"falsefalsefalse2915), "不要")) : ("不要")), "html"nulltrue);
  3181.         } else {
  3182.             echo "不要";
  3183.         }
  3184.         echo "\";
  3185. \t\tvar deck_fence = \"";
  3186.         // line 2916
  3187.         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'2916$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse2916))) {
  3188.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse2916)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"falsefalsefalse2916), "不要")) : ("不要")), "html"nulltrue);
  3189.         } else {
  3190.             echo "不要";
  3191.         }
  3192.         echo "\";
  3193. \t\t// PDF出力: モーダルの mitsumori_json をフォームに同期してから送信
  3194. \t\tfunction syncPdfJson(){
  3195. \t\t\tvar jsonVal = \$('#mitsumori_json').val();
  3196. \t\t\t\$('#pdf_mitsumori_json').val(jsonVal);
  3197. \t\t}
  3198. \t\t// タイプ9: 商品のみ購入
  3199. \t\tfunction quantityOnly(val){
  3200. \t\t\tvar current = parseInt(\$('#quantity_only').val()) || 1;
  3201. \t\t\tvar next = current + val;
  3202. \t\t\tif(next < 1) next = 1;
  3203. \t\t\t\$('#quantity_only').val(next);
  3204. \t\t\t\$('#quantity').val(next);
  3205. \t\t}
  3206.         // ===== スマホ用下部固定バーへの金額同期 =====
  3207.         // mitsumori_message と mitsumori_goukei を監視して下部バーを更新
  3208.         (function() {
  3209.             var msgTarget   = document.getElementById('mitsumori_message');
  3210.             var goukeiTarget = document.getElementById('mitsumori_goukei');
  3211.             var spPrice     = document.getElementById('sp-mitsumori-price');
  3212.             var spBtn       = document.querySelector('#sp-mitsumori-bar .sp-bar__btn');
  3213.             if (!spPrice || !spBtn) return;
  3214.             function syncBar() {
  3215.                 var msg    = msgTarget ? msgTarget.textContent : '';
  3216.                 var goukei = goukeiTarget ? goukeiTarget.textContent : '---円';
  3217.                 // メッセージが「〇〇を選択してください」の場合はメッセージを表示しボタンを非表示
  3218.                 if (msg.indexOf('選択してください') !== -1) {
  3219.                     spPrice.textContent = msg;
  3220.                     spPrice.style.fontSize = '13px';
  3221.                     spPrice.style.color    = '#888';
  3222.                     spBtn.style.display    = 'none';
  3223.                 } else {
  3224.                     // 価格確定時はボタンを表示
  3225.                     spPrice.textContent = goukei;
  3226.                     spPrice.style.fontSize = '18px';
  3227.                     spPrice.style.color    = '#c00';
  3228.                     spBtn.style.display    = 'block';
  3229.                 }
  3230.             }
  3231.             // 初期値を同期
  3232.             syncBar();
  3233.             // mitsumori_message の変化を監視
  3234.             if (msgTarget) {
  3235.                 new MutationObserver(syncBar).observe(
  3236.                     msgTarget, { childList: true, subtree: true, characterData: true }
  3237.                 );
  3238.             }
  3239.             // mitsumori_goukei の変化も監視
  3240.             if (goukeiTarget) {
  3241.                 new MutationObserver(syncBar).observe(
  3242.                     goukeiTarget, { childList: true, subtree: true, characterData: true }
  3243.                 );
  3244.             }
  3245.         })();
  3246.         // ===== 現在のお見積り額: 折りたたみトグルボタンのテキスト切り替え =====
  3247.         (function() {
  3248.             var card = document.querySelector('.mitsumori-card-pc');
  3249.             var btn  = document.querySelector('.btn-mitsumori-toggle .toggle-icon');
  3250.             if (!card || !btn) return;
  3251.             // MutationObserverでcollapsed-cardクラスの変化を監視
  3252.             new MutationObserver(function() {
  3253.                 if (card.classList.contains('collapsed-card')) {
  3254.                     btn.textContent = '▼ 詳細';
  3255.                 } else {
  3256.                     btn.textContent = '▲ 閉じる';
  3257.                 }
  3258.             }).observe(card, { attributes: true, attributeFilter: ['class'] });
  3259.         })();
  3260.         // ===== エリア案内: スマホのみタップで展開 =====
  3261.         (function() {
  3262.             var notice = document.querySelector('.ec-areaNotice');
  3263.             if (!notice) return;
  3264.             notice.addEventListener('click', function(e) {
  3265.                 if (window.innerWidth > 767) return;
  3266.                 // リンククリック時は展開/折りたたみせずリンク遷移
  3267.                 if (e.target.tagName === 'A') return;
  3268.                 notice.classList.toggle('is-open');
  3269.             });
  3270.         })();
  3271.     </script>
  3272.     <script type=\"application/ld+json\">
  3273.     {
  3274.         \"@context\": \"https://schema.org/\",
  3275.         \"@type\": \"Product\",
  3276.         \"name\": \"";
  3277.         // line 3010
  3278.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3010$this->source); })()), "name", [], "any"falsefalsefalse3010), "html"nulltrue);
  3279.         echo "\",
  3280.         \"image\": [
  3281.             ";
  3282.         // line 3012
  3283.         $context['_parent'] = $context;
  3284.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3012$this->source); })()), "ProductImage", [], "any"falsefalsefalse3012));
  3285.         $context['_iterated'] = false;
  3286.         $context['loop'] = [
  3287.           'parent' => $context['_parent'],
  3288.           'index0' => 0,
  3289.           'index'  => 1,
  3290.           'first'  => true,
  3291.         ];
  3292.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3293.             $length count($context['_seq']);
  3294.             $context['loop']['revindex0'] = $length 1;
  3295.             $context['loop']['revindex'] = $length;
  3296.             $context['loop']['length'] = $length;
  3297.             $context['loop']['last'] = === $length;
  3298.         }
  3299.         foreach ($context['_seq'] as $context["_key"] => $context["img"]) {
  3300.             // line 3013
  3301.             echo "                \"";
  3302.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3013$this->source); })()), "request", [], "any"falsefalsefalse3013), "schemeAndHttpHost", [], "any"falsefalsefalse3013), "html"nulltrue);
  3303.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["img"], "save_image"), "html"nulltrue);
  3304.             echo "\"";
  3305.             if ( !twig_get_attribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse3013)) {
  3306.                 echo ",";
  3307.             }
  3308.             // line 3014
  3309.             echo "
  3310.             ";
  3311.             $context['_iterated'] = true;
  3312.             ++$context['loop']['index0'];
  3313.             ++$context['loop']['index'];
  3314.             $context['loop']['first'] = false;
  3315.             if (isset($context['loop']['length'])) {
  3316.                 --$context['loop']['revindex0'];
  3317.                 --$context['loop']['revindex'];
  3318.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3319.             }
  3320.         }
  3321.         if (!$context['_iterated']) {
  3322.             // line 3016
  3323.             echo "                \"";
  3324.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3016$this->source); })()), "request", [], "any"falsefalsefalse3016), "schemeAndHttpHost", [], "any"falsefalsefalse3016), "html"nulltrue);
  3325.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"), "html"nulltrue);
  3326.             echo "\"
  3327.             ";
  3328.         }
  3329.         $_parent $context['_parent'];
  3330.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['img'], $context['_parent'], $context['loop']);
  3331.         $context array_intersect_key($context$_parent) + $_parent;
  3332.         // line 3018
  3333.         echo "        ],
  3334.         \"description\": \"";
  3335.         // line 3019
  3336.         echo twig_escape_filter($this->envtwig_slice($this->envtwig_replace_filter(((twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "description_list", [], "any"truetruefalse3019)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["Product"] ?? null), "description_list", [], "any"falsefalsefalse3019), twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3019$this->source); })()), "description_detail", [], "any"falsefalsefalse3019))) : (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3019$this->source); })()), "description_detail", [], "any"falsefalsefalse3019))), ["
  3337. => """ " => ""]), 0300), "html"nulltrue);
  3338.         echo "\",
  3339.         ";
  3340.         // line 3020
  3341.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3020$this->source); })()), "code_min", [], "any"falsefalsefalse3020)) {
  3342.             // line 3021
  3343.             echo "        \"sku\": \"";
  3344.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3021$this->source); })()), "code_min", [], "any"falsefalsefalse3021), "html"nulltrue);
  3345.             echo "\",
  3346.         ";
  3347.         }
  3348.         // line 3023
  3349.         echo "        \"offers\": {
  3350.             \"@type\": \"Offer\",
  3351.             \"url\": \"";
  3352.         // line 3025
  3353.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_detail", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3025$this->source); })()), "id", [], "any"falsefalsefalse3025)]), "html"nulltrue);
  3354.         echo "\",
  3355.             \"priceCurrency\": \"";
  3356.         // line 3026
  3357.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["eccube_config"]) || array_key_exists("eccube_config"$context) ? $context["eccube_config"] : (function () { throw new RuntimeError('Variable "eccube_config" does not exist.'3026$this->source); })()), "currency", [], "any"falsefalsefalse3026), "html"nulltrue);
  3358.         echo "\",
  3359.             \"price\": ";
  3360.         // line 3027
  3361.         ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3027$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3027)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3027$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3027), "html"nulltrue))) : (print (0)));
  3362.         echo ",
  3363.             \"availability\": \"";
  3364.         // line 3028
  3365.         echo ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3028$this->source); })()), "stock_find", [], "any"falsefalsefalse3028)) ? ("InStock") : ("OutOfStock"));
  3366.         echo "\"
  3367.         }
  3368.     }
  3369.     </script>
  3370. ";
  3371.         
  3372.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  3373.         
  3374.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  3375.     }
  3376.     // line 3035
  3377.     public function block_main($context, array $blocks = [])
  3378.     {
  3379.         $macros $this->macros;
  3380.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  3381.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  3382.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  3383.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  3384.         // line 3036
  3385.         echo "    ";
  3386.         // line 3037
  3387.         echo "    ";
  3388.         $context["option1_label"] = "オプション1";
  3389.         // line 3038
  3390.         echo "    ";
  3391.         $context["option2_label"] = "オプション2";
  3392.         // line 3039
  3393.         echo "    ";
  3394.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3039$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3039))) {
  3395.             // line 3040
  3396.             echo "        ";
  3397.             $context['_parent'] = $context;
  3398.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3040$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3040));
  3399.             foreach ($context['_seq'] as $context["_key"] => $context["pcat"]) {
  3400.                 // line 3041
  3401.                 echo "            ";
  3402.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3041) == 31)) {
  3403.                     $context["option1_label"] = "サイズプリセット";
  3404.                     $context["option2_label"] = "駆動方式";
  3405.                 }
  3406.                 // line 3042
  3407.                 echo "            ";
  3408.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3042) == 43)) {
  3409.                     $context["option1_label"] = "ランマ";
  3410.                     $context["option2_label"] = "タイプ";
  3411.                 }
  3412.                 // line 3043
  3413.                 echo "            ";
  3414.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3043) == 15)) {
  3415.                     $context["option1_label"] = "棚タイプ";
  3416.                 }
  3417.                 // line 3044
  3418.                 echo "            ";
  3419.                 if ((twig_get_attribute($this->env$this->source$context["pcat"], "category_id", [], "any"falsefalsefalse3044) == 17)) {
  3420.                     $context["option1_label"] = "窓タイプ";
  3421.                 }
  3422.                 // line 3045
  3423.                 echo "        ";
  3424.             }
  3425.             $_parent $context['_parent'];
  3426.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pcat'], $context['_parent'], $context['loop']);
  3427.             $context array_intersect_key($context$_parent) + $_parent;
  3428.             // line 3046
  3429.             echo "    ";
  3430.         }
  3431.         // line 3047
  3432.         echo "    <div class=\"ec-productRole\" style=\"margin-top:20px;\">
  3433.         <div class=\"ec-grid2\">
  3434.             <div class=\"ec-grid2__cell\">
  3435.                 <div class=\"ec-sliderItemRole\">
  3436. \t                ";
  3437.         // line 3052
  3438.         echo "\t                <div class=\"ec-productRole__title\">
  3439. \t                    <div class=\"ec-productRole__titleRow\">
  3440. \t                        <h2 class=\"ec-headingTitle\">";
  3441.         // line 3054
  3442.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3054$this->source); })()), "name", [], "any"falsefalsefalse3054), "html"nulltrue);
  3443.         echo "</h2>
  3444. \t                        <div class=\"ec-share-inline\">
  3445. \t                            <a href=\"https://twitter.com/share?url=";
  3446.         // line 3056
  3447.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3056$this->source); })()), "request", [], "any"falsefalsefalse3056), "uri", [], "any"falsefalsefalse3056)), "html"nulltrue);
  3448.         echo "&text=";
  3449.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3056$this->source); })()), "name", [], "any"falsefalsefalse3056)), "html"nulltrue);
  3450.         echo "\"
  3451. \t                               class=\"share-twitter\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Xでシェア\">
  3452. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.74l7.73-8.835L1.254 2.25H8.08l4.254 5.622L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>
  3453. \t                            </a>
  3454. \t                            <a href=\"https://www.instagram.com/\" class=\"share-facebook\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Instagram\">
  3455. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"/></svg>
  3456. \t                            </a>
  3457. \t                            <a href=\"https://social-plugins.line.me/lineit/share?url=";
  3458.         // line 3063
  3459.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'3063$this->source); })()), "request", [], "any"falsefalsefalse3063), "uri", [], "any"falsefalsefalse3063)), "html"nulltrue);
  3460.         echo "\"
  3461. \t                               class=\"share-line\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"LINEでシェア\">
  3462. \t                                <i class=\"fab fa-line\"></i>
  3463. \t                            </a>
  3464. \t                        </div>
  3465. \t                    </div>
  3466. \t                </div>
  3467.                     ";
  3468.         // line 3070
  3469.         if (twig_get_attribute($this->env$this->source, (isset($context["BaseInfo"]) || array_key_exists("BaseInfo"$context) ? $context["BaseInfo"] : (function () { throw new RuntimeError('Variable "BaseInfo" does not exist.'3070$this->source); })()), "option_favorite_product", [], "any"falsefalsefalse3070)) {
  3470.             // line 3071
  3471.             echo "                     <div style=\"position:relative;top: 20px;left: 10px;z-index:100;\">
  3472. \t\t\t\t\t\t";
  3473.             // line 3072
  3474.             if (((isset($context["is_favorite"]) || array_key_exists("is_favorite"$context) ? $context["is_favorite"] : (function () { throw new RuntimeError('Variable "is_favorite" does not exist.'3072$this->source); })()) == false)) {
  3475.                 // line 3073
  3476.                 echo "                        <form action=\"";
  3477.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_favorite", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3073$this->source); })()), "id", [], "any"falsefalsefalse3073)]), "html"nulltrue);
  3478.                 echo "\" method=\"post\">
  3479.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\">&#9825;</button>
  3480.                         </form>
  3481.                         ";
  3482.             } else {
  3483.                 // line 3077
  3484.                 echo "                        <form action=\"";
  3485.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_favorite", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3077$this->source); })()), "id", [], "any"falsefalsefalse3077)]), "html"nulltrue);
  3486.                 echo "\" method=\"post\">
  3487.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\" style=\"color:red;\">&#9829;</button>
  3488.                         </form>
  3489.                         ";
  3490.             }
  3491.             // line 3081
  3492.             echo "                     </div>
  3493.                     ";
  3494.         }
  3495.         // line 3083
  3496.         echo "                    <div class=\"item_visual\">
  3497.                         ";
  3498.         // line 3084
  3499.         $context['_parent'] = $context;
  3500.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3084$this->source); })()), "ProductImage", [], "any"falsefalsefalse3084));
  3501.         $context['_iterated'] = false;
  3502.         $context['loop'] = [
  3503.           'parent' => $context['_parent'],
  3504.           'index0' => 0,
  3505.           'index'  => 1,
  3506.           'first'  => true,
  3507.         ];
  3508.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3509.             $length count($context['_seq']);
  3510.             $context['loop']['revindex0'] = $length 1;
  3511.             $context['loop']['revindex'] = $length;
  3512.             $context['loop']['length'] = $length;
  3513.             $context['loop']['last'] = === $length;
  3514.         }
  3515.         foreach ($context['_seq'] as $context["_key"] => $context["ProductImage"]) {
  3516.             // line 3085
  3517.             echo "                            <div class=\"slide-item\">
  3518.                                 <a class=\"js-zoom\" href=\"";
  3519.             // line 3086
  3520.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3521.             echo "\" aria-label=\"";
  3522.             ((twig_get_attribute($this->env$this->source$context["loop"], "first", [], "any"falsefalsefalse3086)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3086$this->source); })()), "name", [], "any"falsefalsefalse3086), "html"nulltrue))) : (print ("")));
  3523.             echo "\">
  3524.                                     <img src=\"";
  3525.             // line 3087
  3526.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3527.             echo "\" alt=\"";
  3528.             ((twig_get_attribute($this->env$this->source$context["loop"], "first", [], "any"falsefalsefalse3087)) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3087$this->source); })()), "name", [], "any"falsefalsefalse3087), "html"nulltrue))) : (print ("")));
  3529.             echo "\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"";
  3530.             if ((twig_get_attribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse3087) > 1)) {
  3531.                 echo " loading=\"lazy\"";
  3532.             }
  3533.             echo ">
  3534.                                 </a>
  3535.                             </div>
  3536.                         ";
  3537.             $context['_iterated'] = true;
  3538.             ++$context['loop']['index0'];
  3539.             ++$context['loop']['index'];
  3540.             $context['loop']['first'] = false;
  3541.             if (isset($context['loop']['length'])) {
  3542.                 --$context['loop']['revindex0'];
  3543.                 --$context['loop']['revindex'];
  3544.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3545.             }
  3546.         }
  3547.         if (!$context['_iterated']) {
  3548.             // line 3091
  3549.             echo "                            <div class=\"slide-item\"><img src=\"";
  3550.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"), "html"nulltrue);
  3551.             echo "\" alt=\"";
  3552.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3091$this->source); })()), "name", [], "any"falsefalsefalse3091), "html"nulltrue);
  3553.             echo "\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"></div>
  3554.                         ";
  3555.         }
  3556.         $_parent $context['_parent'];
  3557.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductImage'], $context['_parent'], $context['loop']);
  3558.         $context array_intersect_key($context$_parent) + $_parent;
  3559.         // line 3093
  3560.         echo "                    </div>
  3561.                     <div class=\"item_nav\">
  3562.                         ";
  3563.         // line 3095
  3564.         $context['_parent'] = $context;
  3565.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3095$this->source); })()), "ProductImage", [], "any"falsefalsefalse3095));
  3566.         $context['loop'] = [
  3567.           'parent' => $context['_parent'],
  3568.           'index0' => 0,
  3569.           'index'  => 1,
  3570.           'first'  => true,
  3571.         ];
  3572.         if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3573.             $length count($context['_seq']);
  3574.             $context['loop']['revindex0'] = $length 1;
  3575.             $context['loop']['revindex'] = $length;
  3576.             $context['loop']['length'] = $length;
  3577.             $context['loop']['last'] = === $length;
  3578.         }
  3579.         foreach ($context['_seq'] as $context["_key"] => $context["ProductImage"]) {
  3580.             // line 3096
  3581.             echo "                            <div class=\"slideThumb\" data-index=\"";
  3582.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["loop"], "index0", [], "any"falsefalsefalse3096), "html"nulltrue);
  3583.             echo "\"><img src=\"";
  3584.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($context["ProductImage"], "save_image"), "html"nulltrue);
  3585.             echo "\" alt=\"\" width=\"80\" height=\"80\" loading=\"lazy\"></div>
  3586.                         ";
  3587.             ++$context['loop']['index0'];
  3588.             ++$context['loop']['index'];
  3589.             $context['loop']['first'] = false;
  3590.             if (isset($context['loop']['length'])) {
  3591.                 --$context['loop']['revindex0'];
  3592.                 --$context['loop']['revindex'];
  3593.                 $context['loop']['last'] = === $context['loop']['revindex0'];
  3594.             }
  3595.         }
  3596.         $_parent $context['_parent'];
  3597.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductImage'], $context['_parent'], $context['loop']);
  3598.         $context array_intersect_key($context$_parent) + $_parent;
  3599.         // line 3098
  3600.         echo "                    </div>
  3601.                 </div>
  3602.                     ";
  3603.         // line 3103
  3604.         echo "                    <div class=\"ec-areaNotice\" style=\"margin-top:16px;margin-right:10px;\">
  3605.                         <div class=\"ec-areaNotice__inner\">
  3606.                             <div class=\"ec-areaNotice__icon\">📍</div>
  3607.                             <div class=\"ec-areaNotice__body\">
  3608.                                 <p class=\"ec-areaNotice__title\">施工対応エリアについて</p>
  3609.                                 <div class=\"ec-areaNotice__detail\">
  3610.                                     <p class=\"ec-areaNotice__text\">
  3611.                                         当店の施工サービスは、<strong>山梨県全域</strong>および<br>
  3612.                                         <strong>諏訪エリア(諏訪市・岡谷市・茅野市・諏訪郡)</strong>を対象としております。<br>
  3613.                                         上記エリア外のお客様には、商品のみのご購入が可能でございます。<br>
  3614.                                         ご不明な点がございましたら、お気軽にお問い合わせください。
  3615.                                     </p>
  3616.                                     <a class=\"ec-areaNotice__link\" href=\"";
  3617.         // line 3115
  3618.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("contact");
  3619.         echo "\">エリア外のお客様・ご相談はこちら →</a>
  3620.                                 </div>
  3621.                             </div>
  3622.                         </div>
  3623.                     </div>
  3624.             </div>
  3625.             <div class=\"ec-grid2__cell2\">
  3626.                 <div class=\"ec-productRole__profile\" >
  3627.                     ";
  3628.         // line 3126
  3629.         echo "                    ";
  3630.         $context["hidden_cat_ids"] = [=> 21=> 28=> 44];
  3631.         // line 3127
  3632.         echo "                    ";
  3633.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3127$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3127))) {
  3634.             // line 3128
  3635.             echo "                        <div class=\"ec-productRole__category\" style=\"padding:10px 0;\">
  3636.                             ";
  3637.             // line 3129
  3638.             $context['_parent'] = $context;
  3639.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3129$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3129));
  3640.             foreach ($context['_seq'] as $context["_key"] => $context["ProductCategory"]) {
  3641.                 // line 3130
  3642.                 echo "                                ";
  3643.                 if (!twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["ProductCategory"], "Category", [], "any"falsefalsefalse3130), "id", [], "any"falsefalsefalse3130), (isset($context["hidden_cat_ids"]) || array_key_exists("hidden_cat_ids"$context) ? $context["hidden_cat_ids"] : (function () { throw new RuntimeError('Variable "hidden_cat_ids" does not exist.'3130$this->source); })()))) {
  3644.                     // line 3131
  3645.                     echo "                                <ul>
  3646.                                     <li>
  3647.                                         ";
  3648.                     // line 3133
  3649.                     $context['_parent'] = $context;
  3650.                     $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["ProductCategory"], "Category", [], "any"falsefalsefalse3133), "path", [], "any"falsefalsefalse3133));
  3651.                     $context['loop'] = [
  3652.                       'parent' => $context['_parent'],
  3653.                       'index0' => 0,
  3654.                       'index'  => 1,
  3655.                       'first'  => true,
  3656.                     ];
  3657.                     if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  3658.                         $length count($context['_seq']);
  3659.                         $context['loop']['revindex0'] = $length 1;
  3660.                         $context['loop']['revindex'] = $length;
  3661.                         $context['loop']['length'] = $length;
  3662.                         $context['loop']['last'] = === $length;
  3663.                     }
  3664.                     foreach ($context['_seq'] as $context["_key"] => $context["Category"]) {
  3665.                         // line 3134
  3666.                         echo "                                            <a href=\"";
  3667.                         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_list");
  3668.                         echo "?category_id=";
  3669.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Category"], "id", [], "any"falsefalsefalse3134), "html"nulltrue);
  3670.                         echo "\">";
  3671.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Category"], "name", [], "any"falsefalsefalse3134), "html"nulltrue);
  3672.                         echo "</a>";
  3673.                         if ((twig_get_attribute($this->env$this->source$context["loop"], "last", [], "any"falsefalsefalse3134) == false)) {
  3674.                             // line 3135
  3675.                             echo "                                            <span>></span>";
  3676.                         }
  3677.                         ++$context['loop']['index0'];
  3678.                         ++$context['loop']['index'];
  3679.                         $context['loop']['first'] = false;
  3680.                         if (isset($context['loop']['length'])) {
  3681.                             --$context['loop']['revindex0'];
  3682.                             --$context['loop']['revindex'];
  3683.                             $context['loop']['last'] = === $context['loop']['revindex0'];
  3684.                         }
  3685.                     }
  3686.                     $_parent $context['_parent'];
  3687.                     unset($context['_seq'], $context['_iterated'], $context['_key'], $context['Category'], $context['_parent'], $context['loop']);
  3688.                     $context array_intersect_key($context$_parent) + $_parent;
  3689.                     // line 3137
  3690.                     echo "                                    </li>
  3691.                                 </ul>
  3692.                                 ";
  3693.                 }
  3694.                 // line 3140
  3695.                 echo "                            ";
  3696.             }
  3697.             $_parent $context['_parent'];
  3698.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductCategory'], $context['_parent'], $context['loop']);
  3699.             $context array_intersect_key($context$_parent) + $_parent;
  3700.             // line 3141
  3701.             echo "                        </div>
  3702.                     ";
  3703.         }
  3704.         // line 3143
  3705.         echo "                    ";
  3706.         // line 3144
  3707.         echo "                    <div class=\"ec-productRole__price\">
  3708. \t\t\t\t\t\t<span style=\"color:black;font-size:15px;\">工事費込み価格</span>
  3709.                         ";
  3710.         // line 3146
  3711.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3146$this->source); })()), "hasProductClass", [], "any"falsefalsefalse3146)) {
  3712.             // line 3147
  3713.             if ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3147$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3147) == twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3147$this->source); })()), "getPrice02IncTaxMax", [], "any"falsefalsefalse3147))) {
  3714.                 // line 3148
  3715.                 echo "                                <div class=\"ec-price\">
  3716.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">";
  3717.                 // line 3149
  3718.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3149$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3149)), "html"nulltrue);
  3719.                 echo "</span>
  3720.                                     <span class=\"ec-price__tax\">(";
  3721.                 // line 3150
  3722.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("税込"), "html"nulltrue);
  3723.                 echo ")~</span>
  3724.                                 </div>
  3725.                             ";
  3726.             } else {
  3727.                 // line 3153
  3728.                 echo "                                <div class=\"ec-price\">
  3729.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">";
  3730.                 // line 3154
  3731.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3154$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3154)), "html"nulltrue);
  3732.                 echo " ~ ";
  3733.                 echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3154$this->source); })()), "getPrice02IncTaxMax", [], "any"falsefalsefalse3154)), "html"nulltrue);
  3734.                 echo "</span>
  3735.                                     <span class=\"ec-price__tax\">(";
  3736.                 // line 3155
  3737.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("税込"), "html"nulltrue);
  3738.                 echo ")</span>
  3739.                                 </div>
  3740.                             ";
  3741.             }
  3742.             // line 3158
  3743.             echo "                        ";
  3744.         } else {
  3745.             // line 3159
  3746.             echo "                            <div class=\"ec-price\">
  3747.                                 <span id=\"price02-display\" class=\"ec-price__price\">";
  3748.             // line 3160
  3749.             echo twig_escape_filter($this->env$this->extensions['Eccube\Twig\Extension\EccubeExtension']->getPriceFilter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3160$this->source); })()), "getPrice02IncTaxMin", [], "any"falsefalsefalse3160)), "html"nulltrue);
  3750.             echo "</span>
  3751.                                     <span class=\"ec-price__tax\">(";
  3752.             // line 3161
  3753.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("税込"), "html"nulltrue);
  3754.             echo ")~</span>
  3755.                             </div>
  3756.                         ";
  3757.         }
  3758.         // line 3164
  3759.         echo "                    </div>
  3760.                     ";
  3761.         // line 3166
  3762.         echo "                    <ul class=\"ec-productRole__tags\">
  3763.                         ";
  3764.         // line 3167
  3765.         $context['_parent'] = $context;
  3766.         $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3167$this->source); })()), "Tags", [], "any"falsefalsefalse3167));
  3767.         foreach ($context['_seq'] as $context["_key"] => $context["Tag"]) {
  3768.             // line 3168
  3769.             echo "                            <li class=\"ec-productRole__tag tag_";
  3770.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Tag"], "id", [], "any"falsefalsefalse3168), "html"nulltrue);
  3771.             echo "\">";
  3772.             echo twig_escape_filter($this->env$context["Tag"], "html"nulltrue);
  3773.             echo "</li>
  3774.                         ";
  3775.         }
  3776.         $_parent $context['_parent'];
  3777.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['Tag'], $context['_parent'], $context['loop']);
  3778.         $context array_intersect_key($context$_parent) + $_parent;
  3779.         // line 3170
  3780.         echo "                    </ul>
  3781.                     ";
  3782.         // line 3172
  3783.         echo "                    ";
  3784.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3172$this->source); })()), "code_min", [], "any"falsefalsefalse3172))) {
  3785.             // line 3173
  3786.             echo "                        <div class=\"ec-productRole__code\">
  3787.                             ";
  3788.             // line 3174
  3789.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("商品コード"), "html"nulltrue);
  3790.             echo ": <span class=\"product-code-default\">";
  3791.             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3174$this->source); })()), "code_min", [], "any"falsefalsefalse3174), "html"nulltrue);
  3792.             if ((twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3174$this->source); })()), "code_min", [], "any"falsefalsefalse3174) != twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3174$this->source); })()), "code_max", [], "any"falsefalsefalse3174))) {
  3793.                 echo " ~ ";
  3794.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3174$this->source); })()), "code_max", [], "any"falsefalsefalse3174), "html"nulltrue);
  3795.             }
  3796.             echo "</span>
  3797.                         </div>
  3798.                     ";
  3799.         }
  3800.         // line 3177
  3801.         echo "
  3802.                     <div class=\"ec-productRole__description\">
  3803. \t\t\t\t        <div class=\"ec-rectHeading\">
  3804. \t\t\t\t            <h4>製品情報</h4>
  3805. \t\t\t\t        </div>
  3806. \t\t\t\t\t\t";
  3807.         // line 3182
  3808.         echo twig_nl2br(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3182$this->source); })()), "sales_infomation", [], "any"falsefalsefalse3182));
  3809.         echo "
  3810.                     </div>
  3811. \t\t\t\t\t<div class=\"card card-danger\" style=\"clear:both;margin:1px;\">
  3812. \t\t\t\t\t  <div class=\"card-header\">
  3813. \t\t\t\t\t    <h3 class=\"card-title\">見積シミュレーション</h3>
  3814. \t\t\t\t\t  </div>
  3815. \t\t\t\t\t  <div class=\"card-body p-2\">
  3816.                         ";
  3817.         // line 3191
  3818.         $context["related_image"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3191$this->source); })()), "id", [], "any"falsefalsefalse3191), "related_image");
  3819.         // line 3192
  3820.         echo "                        ";
  3821.         // line 3193
  3822.         echo "                        ";
  3823.         $context["img1"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3193$this->source); })()) && twig_in_filter("1段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3193$this->source); })())));
  3824.         // line 3194
  3825.         echo "                        ";
  3826.         $context["img2"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3194$this->source); })()) && twig_in_filter("2段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3194$this->source); })())));
  3827.         // line 3195
  3828.         echo "                        ";
  3829.         $context["img3"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3195$this->source); })()) && twig_in_filter("3段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3195$this->source); })())));
  3830.         // line 3196
  3831.         echo "                        ";
  3832.         $context["img4"] = ((isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3196$this->source); })()) && twig_in_filter("4段目画像あり", (isset($context["related_image"]) || array_key_exists("related_image"$context) ? $context["related_image"] : (function () { throw new RuntimeError('Variable "related_image" does not exist.'3196$this->source); })())));
  3833.         // line 3197
  3834.         echo "\t\t\t\t\t    ";
  3835.         $context["type1"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3197$this->source); })()), "id", [], "any"falsefalsefalse3197), "related_name1");
  3836.         // line 3198
  3837.         echo "\t\t\t\t\t\t";
  3838.         $context["type2"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3198$this->source); })()), "id", [], "any"falsefalsefalse3198), "related_name2");
  3839.         // line 3199
  3840.         echo "\t\t\t\t\t\t";
  3841.         $context["type3"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3199$this->source); })()), "id", [], "any"falsefalsefalse3199), "related_name3");
  3842.         // line 3200
  3843.         echo "\t\t\t\t\t\t";
  3844.         $context["type4"] = $this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3200$this->source); })()), "id", [], "any"falsefalsefalse3200), "related_name4");
  3845.         // line 3201
  3846.         echo "\t\t\t\t\t\t";
  3847.         $context["hasRelated"] = ((((((isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3201$this->source); })()) && (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3201$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3201$this->source); })()))) || ((        // line 3202
  3848. (isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3202$this->source); })()) && (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3202$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3202$this->source); })())))) || ((        // line 3203
  3849. (isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3203$this->source); })()) && (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3203$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3203$this->source); })())))) || ((        // line 3204
  3850. (isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3204$this->source); })()) && (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3204$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3204$this->source); })()))));
  3851.         // line 3205
  3852.         echo "\t\t\t\t\t\t";
  3853.         if ((isset($context["hasRelated"]) || array_key_exists("hasRelated"$context) ? $context["hasRelated"] : (function () { throw new RuntimeError('Variable "hasRelated" does not exist.'3205$this->source); })())) {
  3854.             // line 3206
  3855.             echo "\t\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のタイプを選択してください。</label></div>
  3856. \t\t\t\t\t\t";
  3857.         }
  3858.         // line 3208
  3859.         echo "
  3860. \t\t\t\t\t\t";
  3861.         // line 3210
  3862.         echo "\t\t\t\t\t\t";
  3863.         if ((((isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3210$this->source); })()) && (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3210$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3210$this->source); })())))) {
  3864.             // line 3211
  3865.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  3866. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  3867.             // line 3212
  3868.             echo twig_escape_filter($this->env, (isset($context["type1"]) || array_key_exists("type1"$context) ? $context["type1"] : (function () { throw new RuntimeError('Variable "type1" does not exist.'3212$this->source); })()), "html"nulltrue);
  3869.             if (((isset($context["img1"]) || array_key_exists("img1"$context) ? $context["img1"] : (function () { throw new RuntimeError('Variable "img1" does not exist.'3212$this->source); })()) && (isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3212$this->source); })()))) {
  3870.                 echo ": <span>";
  3871.                 echo twig_escape_filter($this->env, (isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3212$this->source); })()), "html"nulltrue);
  3872.                 echo "</span>";
  3873.             }
  3874.             echo "</div>
  3875. \t\t\t\t\t\t  ";
  3876.             // line 3213
  3877.             if ((isset($context["img1"]) || array_key_exists("img1"$context) ? $context["img1"] : (function () { throw new RuntimeError('Variable "img1" does not exist.'3213$this->source); })())) {
  3878.                 // line 3214
  3879.                 echo "\t\t\t\t\t\t    ";
  3880.                 // line 3215
  3881.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  3882. \t\t\t\t\t\t      ";
  3883.                 // line 3216
  3884.                 $context['_parent'] = $context;
  3885.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3216$this->source); })()));
  3886.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  3887.                     // line 3217
  3888.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  3889.                     if (((isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3217$this->source); })()) == $context["rp_name"])) {
  3890.                         echo " is-selected";
  3891.                     }
  3892.                     echo "\" href=\"/products/detail/";
  3893.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  3894.                     echo "\">
  3895. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  3896. \t\t\t\t\t\t               src=\"";
  3897.                     // line 3219
  3898.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3219) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3219$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3219))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3219$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3219), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  3899.                     echo "\"
  3900. \t\t\t\t\t\t               alt=\"";
  3901.                     // line 3220
  3902.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  3903.                     echo "\"
  3904. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  3905. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  3906. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  3907. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  3908.                     // line 3224
  3909.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  3910.                     echo "</span>
  3911. \t\t\t\t\t\t        </a>
  3912. \t\t\t\t\t\t      ";
  3913.                 }
  3914.                 $_parent $context['_parent'];
  3915.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  3916.                 $context array_intersect_key($context$_parent) + $_parent;
  3917.                 // line 3227
  3918.                 echo "\t\t\t\t\t\t    </div>
  3919. \t\t\t\t\t\t  ";
  3920.             } else {
  3921.                 // line 3229
  3922.                 echo "\t\t\t\t\t\t    ";
  3923.                 // line 3230
  3924.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  3925. \t\t\t\t\t\t      ";
  3926.                 // line 3231
  3927.                 $context['_parent'] = $context;
  3928.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product1"]) || array_key_exists("related_product1"$context) ? $context["related_product1"] : (function () { throw new RuntimeError('Variable "related_product1" does not exist.'3231$this->source); })()));
  3929.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  3930.                     // line 3232
  3931.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  3932.                     if (((isset($context["base_select1"]) || array_key_exists("base_select1"$context) ? $context["base_select1"] : (function () { throw new RuntimeError('Variable "base_select1" does not exist.'3232$this->source); })()) == $context["rp_name"])) {
  3933.                         echo " is-selected";
  3934.                     }
  3935.                     echo "\" href=\"/products/detail/";
  3936.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  3937.                     echo "\">
  3938. \t\t\t\t\t\t          ";
  3939.                     // line 3233
  3940.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  3941.                     echo "
  3942. \t\t\t\t\t\t        </a>
  3943. \t\t\t\t\t\t      ";
  3944.                 }
  3945.                 $_parent $context['_parent'];
  3946.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  3947.                 $context array_intersect_key($context$_parent) + $_parent;
  3948.                 // line 3236
  3949.                 echo "\t\t\t\t\t\t    </div>
  3950. \t\t\t\t\t\t  ";
  3951.             }
  3952.             // line 3238
  3953.             echo "\t\t\t\t\t\t</div>
  3954. \t\t\t\t\t\t";
  3955.         }
  3956.         // line 3240
  3957.         echo "
  3958. \t\t\t\t\t\t";
  3959.         // line 3242
  3960.         echo "\t\t\t\t\t\t";
  3961.         if ((((isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3242$this->source); })()) && (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3242$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3242$this->source); })())))) {
  3962.             // line 3243
  3963.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  3964. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  3965.             // line 3244
  3966.             echo twig_escape_filter($this->env, (isset($context["type2"]) || array_key_exists("type2"$context) ? $context["type2"] : (function () { throw new RuntimeError('Variable "type2" does not exist.'3244$this->source); })()), "html"nulltrue);
  3967.             if (((isset($context["img2"]) || array_key_exists("img2"$context) ? $context["img2"] : (function () { throw new RuntimeError('Variable "img2" does not exist.'3244$this->source); })()) && (isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3244$this->source); })()))) {
  3968.                 echo ": <span>";
  3969.                 echo twig_escape_filter($this->env, (isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3244$this->source); })()), "html"nulltrue);
  3970.                 echo "</span>";
  3971.             }
  3972.             echo "</div>
  3973. \t\t\t\t\t\t  ";
  3974.             // line 3245
  3975.             if ((isset($context["img2"]) || array_key_exists("img2"$context) ? $context["img2"] : (function () { throw new RuntimeError('Variable "img2" does not exist.'3245$this->source); })())) {
  3976.                 // line 3246
  3977.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  3978. \t\t\t\t\t\t      ";
  3979.                 // line 3247
  3980.                 $context['_parent'] = $context;
  3981.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3247$this->source); })()));
  3982.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  3983.                     // line 3248
  3984.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  3985.                     if (((isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3248$this->source); })()) == $context["rp_name"])) {
  3986.                         echo " is-selected";
  3987.                     }
  3988.                     echo "\" href=\"/products/detail/";
  3989.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  3990.                     echo "\">
  3991. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  3992. \t\t\t\t\t\t               src=\"";
  3993.                     // line 3250
  3994.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3250) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3250$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3250))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3250$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3250), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  3995.                     echo "\"
  3996. \t\t\t\t\t\t               alt=\"";
  3997.                     // line 3251
  3998.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  3999.                     echo "\"
  4000. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4001. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4002. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4003. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4004.                     // line 3255
  4005.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4006.                     echo "</span>
  4007. \t\t\t\t\t\t        </a>
  4008. \t\t\t\t\t\t      ";
  4009.                 }
  4010.                 $_parent $context['_parent'];
  4011.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4012.                 $context array_intersect_key($context$_parent) + $_parent;
  4013.                 // line 3258
  4014.                 echo "\t\t\t\t\t\t    </div>
  4015. \t\t\t\t\t\t  ";
  4016.             } else {
  4017.                 // line 3260
  4018.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4019. \t\t\t\t\t\t      ";
  4020.                 // line 3261
  4021.                 $context['_parent'] = $context;
  4022.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product2"]) || array_key_exists("related_product2"$context) ? $context["related_product2"] : (function () { throw new RuntimeError('Variable "related_product2" does not exist.'3261$this->source); })()));
  4023.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4024.                     // line 3262
  4025.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4026.                     if (((isset($context["base_select2"]) || array_key_exists("base_select2"$context) ? $context["base_select2"] : (function () { throw new RuntimeError('Variable "base_select2" does not exist.'3262$this->source); })()) == $context["rp_name"])) {
  4027.                         echo " is-selected";
  4028.                     }
  4029.                     echo "\" href=\"/products/detail/";
  4030.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4031.                     echo "\">
  4032. \t\t\t\t\t\t          ";
  4033.                     // line 3263
  4034.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4035.                     echo "
  4036. \t\t\t\t\t\t        </a>
  4037. \t\t\t\t\t\t      ";
  4038.                 }
  4039.                 $_parent $context['_parent'];
  4040.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4041.                 $context array_intersect_key($context$_parent) + $_parent;
  4042.                 // line 3266
  4043.                 echo "\t\t\t\t\t\t    </div>
  4044. \t\t\t\t\t\t  ";
  4045.             }
  4046.             // line 3268
  4047.             echo "\t\t\t\t\t\t</div>
  4048. \t\t\t\t\t\t";
  4049.         }
  4050.         // line 3270
  4051.         echo "
  4052. \t\t\t\t\t\t";
  4053.         // line 3272
  4054.         echo "\t\t\t\t\t\t";
  4055.         if ((((isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3272$this->source); })()) && (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3272$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3272$this->source); })())))) {
  4056.             // line 3273
  4057.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4058. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4059.             // line 3274
  4060.             echo twig_escape_filter($this->env, (isset($context["type3"]) || array_key_exists("type3"$context) ? $context["type3"] : (function () { throw new RuntimeError('Variable "type3" does not exist.'3274$this->source); })()), "html"nulltrue);
  4061.             if (((isset($context["img3"]) || array_key_exists("img3"$context) ? $context["img3"] : (function () { throw new RuntimeError('Variable "img3" does not exist.'3274$this->source); })()) && (isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3274$this->source); })()))) {
  4062.                 echo ": <span>";
  4063.                 echo twig_escape_filter($this->env, (isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3274$this->source); })()), "html"nulltrue);
  4064.                 echo "</span>";
  4065.             }
  4066.             echo "</div>
  4067. \t\t\t\t\t\t  ";
  4068.             // line 3275
  4069.             if ((isset($context["img3"]) || array_key_exists("img3"$context) ? $context["img3"] : (function () { throw new RuntimeError('Variable "img3" does not exist.'3275$this->source); })())) {
  4070.                 // line 3276
  4071.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4072. \t\t\t\t\t\t      ";
  4073.                 // line 3277
  4074.                 $context['_parent'] = $context;
  4075.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3277$this->source); })()));
  4076.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4077.                     // line 3278
  4078.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4079.                     if (((isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3278$this->source); })()) == $context["rp_name"])) {
  4080.                         echo " is-selected";
  4081.                     }
  4082.                     echo "\" href=\"/products/detail/";
  4083.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4084.                     echo "\">
  4085. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4086. \t\t\t\t\t\t               src=\"";
  4087.                     // line 3280
  4088.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3280) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3280$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3280))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3280$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3280), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4089.                     echo "\"
  4090. \t\t\t\t\t\t               alt=\"";
  4091.                     // line 3281
  4092.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4093.                     echo "\"
  4094. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  4095. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  4096. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  4097. \t\t\t\t\t\t          <span class=\"rp-card__name\">";
  4098.                     // line 3285
  4099.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4100.                     echo "</span>
  4101. \t\t\t\t\t\t        </a>
  4102. \t\t\t\t\t\t      ";
  4103.                 }
  4104.                 $_parent $context['_parent'];
  4105.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4106.                 $context array_intersect_key($context$_parent) + $_parent;
  4107.                 // line 3288
  4108.                 echo "\t\t\t\t\t\t    </div>
  4109. \t\t\t\t\t\t  ";
  4110.             } else {
  4111.                 // line 3290
  4112.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4113. \t\t\t\t\t\t      ";
  4114.                 // line 3291
  4115.                 $context['_parent'] = $context;
  4116.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product3"]) || array_key_exists("related_product3"$context) ? $context["related_product3"] : (function () { throw new RuntimeError('Variable "related_product3" does not exist.'3291$this->source); })()));
  4117.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4118.                     // line 3292
  4119.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4120.                     if (((isset($context["base_select3"]) || array_key_exists("base_select3"$context) ? $context["base_select3"] : (function () { throw new RuntimeError('Variable "base_select3" does not exist.'3292$this->source); })()) == $context["rp_name"])) {
  4121.                         echo " is-selected";
  4122.                     }
  4123.                     echo "\" href=\"/products/detail/";
  4124.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4125.                     echo "\">
  4126. \t\t\t\t\t\t          ";
  4127.                     // line 3293
  4128.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4129.                     echo "
  4130. \t\t\t\t\t\t        </a>
  4131. \t\t\t\t\t\t      ";
  4132.                 }
  4133.                 $_parent $context['_parent'];
  4134.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4135.                 $context array_intersect_key($context$_parent) + $_parent;
  4136.                 // line 3296
  4137.                 echo "\t\t\t\t\t\t    </div>
  4138. \t\t\t\t\t\t  ";
  4139.             }
  4140.             // line 3298
  4141.             echo "\t\t\t\t\t\t</div>
  4142. \t\t\t\t\t\t";
  4143.         }
  4144.         // line 3300
  4145.         echo "
  4146. \t\t\t\t\t\t";
  4147.         // line 3302
  4148.         echo "\t\t\t\t\t\t";
  4149.         if ((((isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3302$this->source); })()) && (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3302$this->source); })())) && twig_length_filter($this->env, (isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3302$this->source); })())))) {
  4150.             // line 3303
  4151.             echo "\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4152. \t\t\t\t\t\t  <div class=\"rp-section-label\">";
  4153.             // line 3304
  4154.             echo twig_escape_filter($this->env, (isset($context["type4"]) || array_key_exists("type4"$context) ? $context["type4"] : (function () { throw new RuntimeError('Variable "type4" does not exist.'3304$this->source); })()), "html"nulltrue);
  4155.             if (((isset($context["img4"]) || array_key_exists("img4"$context) ? $context["img4"] : (function () { throw new RuntimeError('Variable "img4" does not exist.'3304$this->source); })()) && (isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3304$this->source); })()))) {
  4156.                 echo ": <span>";
  4157.                 echo twig_escape_filter($this->env, (isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3304$this->source); })()), "html"nulltrue);
  4158.                 echo "</span>";
  4159.             }
  4160.             echo "</div>
  4161. \t\t\t\t\t\t  ";
  4162.             // line 3305
  4163.             if ((isset($context["img4"]) || array_key_exists("img4"$context) ? $context["img4"] : (function () { throw new RuntimeError('Variable "img4" does not exist.'3305$this->source); })())) {
  4164.                 // line 3306
  4165.                 echo "\t\t\t\t\t\t    ";
  4166.                 // line 3307
  4167.                 echo "\t\t\t\t\t\t    <div class=\"rp-card-group\">
  4168. \t\t\t\t\t\t      ";
  4169.                 // line 3308
  4170.                 $context['_parent'] = $context;
  4171.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3308$this->source); })()));
  4172.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4173.                     // line 3309
  4174.                     echo "\t\t\t\t\t\t        <a class=\"rp-card";
  4175.                     if (((isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3309$this->source); })()) == $context["rp_name"])) {
  4176.                         echo " is-selected";
  4177.                     }
  4178.                     echo "\" href=\"/products/detail/";
  4179.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4180.                     echo "\">
  4181. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  4182. \t\t\t\t\t\t               src=\"";
  4183.                     // line 3311
  4184.                     echo twig_escape_filter($this->env, (((twig_get_attribute($this->env$this->source, ($context["related_image_obj"] ?? null), $context["rp_id"], [], "array"truetruefalse3311) && twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3311$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3311))) ? ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(twig_get_attribute($this->env$this->source, (isset($context["related_image_obj"]) || array_key_exists("related_image_obj"$context) ? $context["related_image_obj"] : (function () { throw new RuntimeError('Variable "related_image_obj" does not exist.'3311$this->source); })()), $context["rp_id"], [], "array"falsefalsefalse3311), "save_image")) : ($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(""), "save_image"))), "html"nulltrue);
  4185.                     echo "\"
  4186. \t\t\t\t\t\t               alt=\"";
  4187.                     // line 3312
  4188.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4189.                     echo "\" width=\"120\" height=\"120\" loading=\"lazy\">
  4190. \t\t\t\t\t\t          <span class=\"rp-card__label\">";
  4191.                     // line 3313
  4192.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4193.                     echo "</span>
  4194. \t\t\t\t\t\t        </a>
  4195. \t\t\t\t\t\t      ";
  4196.                 }
  4197.                 $_parent $context['_parent'];
  4198.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4199.                 $context array_intersect_key($context$_parent) + $_parent;
  4200.                 // line 3316
  4201.                 echo "\t\t\t\t\t\t    </div>
  4202. \t\t\t\t\t\t  ";
  4203.             } else {
  4204.                 // line 3318
  4205.                 echo "\t\t\t\t\t\t    ";
  4206.                 // line 3319
  4207.                 echo "\t\t\t\t\t\t    <div class=\"rp-btn-group\">
  4208. \t\t\t\t\t\t      ";
  4209.                 // line 3320
  4210.                 $context['_parent'] = $context;
  4211.                 $context['_seq'] = twig_ensure_traversable((isset($context["related_product4"]) || array_key_exists("related_product4"$context) ? $context["related_product4"] : (function () { throw new RuntimeError('Variable "related_product4" does not exist.'3320$this->source); })()));
  4212.                 foreach ($context['_seq'] as $context["rp_id"] => $context["rp_name"]) {
  4213.                     // line 3321
  4214.                     echo "\t\t\t\t\t\t        <a class=\"rp-btn";
  4215.                     if (((isset($context["base_select4"]) || array_key_exists("base_select4"$context) ? $context["base_select4"] : (function () { throw new RuntimeError('Variable "base_select4" does not exist.'3321$this->source); })()) == $context["rp_name"])) {
  4216.                         echo " is-selected";
  4217.                     }
  4218.                     echo "\" href=\"/products/detail/";
  4219.                     echo twig_escape_filter($this->env$context["rp_id"], "html"nulltrue);
  4220.                     echo "\">
  4221. \t\t\t\t\t\t          ";
  4222.                     // line 3322
  4223.                     echo twig_escape_filter($this->env$context["rp_name"], "html"nulltrue);
  4224.                     echo "
  4225. \t\t\t\t\t\t        </a>
  4226. \t\t\t\t\t\t      ";
  4227.                 }
  4228.                 $_parent $context['_parent'];
  4229.                 unset($context['_seq'], $context['_iterated'], $context['rp_id'], $context['rp_name'], $context['_parent'], $context['loop']);
  4230.                 $context array_intersect_key($context$_parent) + $_parent;
  4231.                 // line 3325
  4232.                 echo "\t\t\t\t\t\t    </div>
  4233. \t\t\t\t\t\t  ";
  4234.             }
  4235.             // line 3327
  4236.             echo "\t\t\t\t\t\t</div>
  4237. \t\t\t\t\t\t";
  4238.         }
  4239.         // line 3329
  4240.         echo "
  4241. \t\t\t\t\t    ";
  4242.         // line 3338
  4243.         echo "\t\t\t\t\t    ";
  4244.         $context["is_gs_h"] = false;
  4245.         // line 3339
  4246.         echo "\t\t\t\t\t    ";
  4247.         $context["is_cg_h"] = false;
  4248.         // line 3340
  4249.         echo "\t\t\t\t\t    ";
  4250.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3340$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3340))) {
  4251.             // line 3341
  4252.             echo "\t\t\t\t\t        ";
  4253.             $context['_parent'] = $context;
  4254.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3341$this->source); })()), "ProductCategories", [], "any"falsefalsefalse3341));
  4255.             foreach ($context['_seq'] as $context["_key"] => $context["pc_h"]) {
  4256.                 // line 3342
  4257.                 echo "\t\t\t\t\t            ";
  4258.                 if ((twig_get_attribute($this->env$this->source$context["pc_h"], "category_id", [], "any"falsefalsefalse3342) == 27)) {
  4259.                     $context["is_gs_h"] = true;
  4260.                 }
  4261.                 // line 3343
  4262.                 echo "\t\t\t\t\t            ";
  4263.                 if ((twig_get_attribute($this->env$this->source$context["pc_h"], "category_id", [], "any"falsefalsefalse3343) == 9)) {
  4264.                     $context["is_cg_h"] = true;
  4265.                 }
  4266.                 // line 3344
  4267.                 echo "\t\t\t\t\t        ";
  4268.             }
  4269.             $_parent $context['_parent'];
  4270.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pc_h'], $context['_parent'], $context['loop']);
  4271.             $context array_intersect_key($context$_parent) + $_parent;
  4272.             // line 3345
  4273.             echo "\t\t\t\t\t    ";
  4274.         }
  4275.         // line 3346
  4276.         echo "\t\t\t\t\t    ";
  4277.         $context["visible_op_count"] = 0;
  4278.         // line 3347
  4279.         echo "\t\t\t\t\t    ";
  4280.         if (((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3347$this->source); })()) && twig_length_filter($this->env, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3347$this->source); })())))) {
  4281.             // line 3348
  4282.             echo "\t\t\t\t\t        ";
  4283.             $context['_parent'] = $context;
  4284.             $context['_seq'] = twig_ensure_traversable((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'3348$this->source); })()));
  4285.             foreach ($context['_seq'] as $context["_key"] => $context["opi"]) {
  4286.                 // line 3349
  4287.                 echo "\t\t\t\t\t            ";
  4288.                 if (twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3349)) {
  4289.                     // line 3350
  4290.                     echo "\t\t\t\t\t                ";
  4291.                     $context["_hide_h"] = false;
  4292.                     // line 3351
  4293.                     echo "\t\t\t\t\t                ";
  4294.                     if (((isset($context["is_gs_h"]) || array_key_exists("is_gs_h"$context) ? $context["is_gs_h"] : (function () { throw new RuntimeError('Variable "is_gs_h" does not exist.'3351$this->source); })()) && (preg_match("/撤去/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3351)) || preg_match("/残土/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3351))))) {
  4295.                         $context["_hide_h"] = true;
  4296.                     }
  4297.                     // line 3352
  4298.                     echo "\t\t\t\t\t                ";
  4299.                     if (((isset($context["is_cg_h"]) || array_key_exists("is_cg_h"$context) ? $context["is_cg_h"] : (function () { throw new RuntimeError('Variable "is_cg_h" does not exist.'3352$this->source); })()) && preg_match("/残土/"twig_get_attribute($this->env$this->source$context["opi"], "name", [], "array"falsefalsefalse3352)))) {
  4300.                         $context["_hide_h"] = true;
  4301.                     }
  4302.                     // line 3353
  4303.                     echo "\t\t\t\t\t                ";
  4304.                     if ( !(isset($context["_hide_h"]) || array_key_exists("_hide_h"$context) ? $context["_hide_h"] : (function () { throw new RuntimeError('Variable "_hide_h" does not exist.'3353$this->source); })())) {
  4305.                         $context["visible_op_count"] = ((isset($context["visible_op_count"]) || array_key_exists("visible_op_count"$context) ? $context["visible_op_count"] : (function () { throw new RuntimeError('Variable "visible_op_count" does not exist.'3353$this->source); })()) + 1);
  4306.                     }
  4307.                     // line 3354
  4308.                     echo "\t\t\t\t\t            ";
  4309.                 }
  4310.                 // line 3355
  4311.                 echo "\t\t\t\t\t        ";
  4312.             }
  4313.             $_parent $context['_parent'];
  4314.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opi'], $context['_parent'], $context['loop']);
  4315.             $context array_intersect_key($context$_parent) + $_parent;
  4316.             // line 3356
  4317.             echo "\t\t\t\t\t    ";
  4318.         }
  4319.         // line 3357
  4320.         echo "\t\t\t\t\t    ";
  4321.         $context["has_any_option"] = (((((((((        // line 3358
  4322. (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3358$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3358$this->source); })()))) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3358$this->source); })()), "SaleType", [], "any"falsefalsefalse3358), "id", [], "any"falsefalsefalse3358) != 3)) || ((        // line 3359
  4323. (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3359$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3359$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3359$this->source); })())) != ""))) || ((        // line 3360
  4324. (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3360$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3360$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3360$this->source); })())) != ""))) || ((        // line 3361
  4325. (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3361$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3361$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3361$this->source); })())) != ""))) || ((        // line 3362
  4326. (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3362$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3362$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3362$this->source); })())) != ""))) || ((        // line 3363
  4327. (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3363$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3363$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3363$this->source); })())) != ""))) || ((        // line 3364
  4328. (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3364$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3364$this->source); })()))) && (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3364$this->source); })())) != ""))) || twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source,         // line 3365
  4329. (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3365$this->source); })()), "SaleType", [], "any"falsefalsefalse3365), "id", [], "any"falsefalsefalse3365), [=> 2=> 5=> 6=> 7=> 9]));
  4330.         // line 3367
  4331.         echo "\t\t\t\t\t    ";
  4332.         if ((isset($context["has_any_option"]) || array_key_exists("has_any_option"$context) ? $context["has_any_option"] : (function () { throw new RuntimeError('Variable "has_any_option" does not exist.'3367$this->source); })())) {
  4333.             // line 3368
  4334.             echo "\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のオプションを選択してください。</label></div>
  4335. \t\t\t\t\t    ";
  4336.         }
  4337.         // line 3370
  4338.         echo "
  4339.                         ";
  4340.         // line 3372
  4341.         echo "                        ";
  4342.         if (((((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3372$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3372$this->source); })()))) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3372$this->source); })()), "SaleType", [], "any"falsefalsefalse3372), "id", [], "any"falsefalsefalse3372) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3372$this->source); })()), "SaleType", [], "any"falsefalsefalse3372), "id", [], "any"falsefalsefalse3372) != 2))) {
  4343.             // line 3373
  4344.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4345.                           <div class=\"rp-section-label\">カラー";
  4346.             // line 3374
  4347.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3374$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3374$this->source); })()), "pc", [], "any"falsefalsefalse3374))) {
  4348.                 echo ": <span>";
  4349.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3374$this->source); })()), "pc", [], "any"falsefalsefalse3374), "html"nulltrue);
  4350.                 echo "</span>";
  4351.             }
  4352.             echo "</div>
  4353.                           <div class=\"opt-btn-group\">
  4354.                             ";
  4355.             // line 3376
  4356.             $context["idx"] = 0;
  4357.             // line 3377
  4358.             echo "                            ";
  4359.             $context['_parent'] = $context;
  4360.             $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3377$this->source); })()));
  4361.             foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  4362.                 if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3377))) {
  4363.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3377$this->source); })()) + 1);
  4364.                     // line 3378
  4365.                     echo "                              ";
  4366.                     $context["has_img"] = (twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"truetruefalse3378) &&  !twig_test_empty(twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3378)));
  4367.                     // line 3379
  4368.                     echo "                              <label class=\"opt-btn";
  4369.                     if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3379$this->source); })())) {
  4370.                         echo " opt-btn--with-image";
  4371.                     }
  4372.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3379$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3379$this->source); })()), "pc", [], "any"falsefalsefalse3379) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3379))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3379$this->source); })())) == 1))) {
  4373.                         echo " is-selected";
  4374.                     }
  4375.                     echo "\"
  4376.                                      onclick=\"mitsumori_simulation_val('pc', '";
  4377.                     // line 3380
  4378.                     echo twig_escape_filter($this->envtwig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3380), "js"), "html"nulltrue);
  4379.                     echo "');\">
  4380.                                 <input type=\"radio\" name=\"color\" id=\"cc_";
  4381.                     // line 3381
  4382.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3381$this->source); })()), "html"nulltrue);
  4383.                     echo "\" value=\"";
  4384.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3381), "html"nulltrue);
  4385.                     echo "\"
  4386.                                        ";
  4387.                     // line 3382
  4388.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3382$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3382$this->source); })()), "pc", [], "any"falsefalsefalse3382) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3382))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3382$this->source); })())) == 1))) {
  4389.                         echo "checked";
  4390.                     }
  4391.                     echo ">
  4392.                                 ";
  4393.                     // line 3383
  4394.                     if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3383$this->source); })())) {
  4395.                         // line 3384
  4396.                         echo "                                  <img src=\"";
  4397.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3384), "html"nulltrue);
  4398.                         echo "\" alt=\"";
  4399.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3384), "html"nulltrue);
  4400.                         echo "\" class=\"opt-btn__img\"
  4401.                                        onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  4402.                                   <span class=\"opt-btn__name\">";
  4403.                         // line 3386
  4404.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3386), "html"nulltrue);
  4405.                         echo "</span>
  4406.                                 ";
  4407.                     } else {
  4408.                         // line 3388
  4409.                         echo "                                  ";
  4410.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3388), "html"nulltrue);
  4411.                         echo "
  4412.                                 ";
  4413.                     }
  4414.                     // line 3390
  4415.                     echo "                              </label>
  4416.                             ";
  4417.                 }
  4418.             }
  4419.             $_parent $context['_parent'];
  4420.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  4421.             $context array_intersect_key($context$_parent) + $_parent;
  4422.             // line 3392
  4423.             echo "                          </div>
  4424.                         </div>
  4425.                         ";
  4426.         }
  4427.         // line 3395
  4428.         echo "
  4429.                         ";
  4430.         // line 3400
  4431.         echo "                        ";
  4432.         if (((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3400$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3400$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3400$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3400$this->source); })()), "SaleType", [], "any"falsefalsefalse3400), "id", [], "any"falsefalsefalse3400), [=> 2=> 3=> 6]))) {
  4433.             // line 3401
  4434.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4435.                           <div class=\"rp-section-label\">幅";
  4436.             // line 3402
  4437.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3402$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3402$this->source); })()), "pw", [], "any"falsefalsefalse3402))) {
  4438.                 echo ": <span>";
  4439.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3402$this->source); })()), "pw", [], "any"falsefalsefalse3402), "html"nulltrue);
  4440.                 echo "</span>";
  4441.             }
  4442.             echo "</div>
  4443.                           <div class=\"opt-btn-group\">
  4444.                             ";
  4445.             // line 3404
  4446.             $context["idx"] = 0;
  4447.             // line 3405
  4448.             echo "                            ";
  4449.             $context['_parent'] = $context;
  4450.             $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3405$this->source); })()));
  4451.             foreach ($context['_seq'] as $context["_key"] => $context["pw"]) {
  4452.                 if ($context["pw"]) {
  4453.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3405$this->source); })()) + 1);
  4454.                     // line 3406
  4455.                     echo "                              <label class=\"opt-btn";
  4456.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3406$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3406$this->source); })()), "pw", [], "any"falsefalsefalse3406) == $context["pw"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3406$this->source); })())) == 1))) {
  4457.                         echo " is-selected";
  4458.                     }
  4459.                     echo "\"
  4460.                                      onclick=\"mitsumori_simulation_val('pw', '";
  4461.                     // line 3407
  4462.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pw"], "js"), "html"nulltrue);
  4463.                     echo "');\">
  4464.                                 <input type=\"radio\" name=\"pw\" id=\"pw_";
  4465.                     // line 3408
  4466.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3408$this->source); })()), "html"nulltrue);
  4467.                     echo "\" value=\"";
  4468.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  4469.                     echo "\"
  4470.                                        ";
  4471.                     // line 3409
  4472.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3409$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3409$this->source); })()), "pw", [], "any"falsefalsefalse3409) == $context["pw"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3409$this->source); })())) == 1))) {
  4473.                         echo "checked";
  4474.                     }
  4475.                     echo ">
  4476.                                 ";
  4477.                     // line 3410
  4478.                     echo twig_escape_filter($this->env$context["pw"], "html"nulltrue);
  4479.                     echo "
  4480.                               </label>
  4481.                             ";
  4482.                 }
  4483.             }
  4484.             $_parent $context['_parent'];
  4485.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw'], $context['_parent'], $context['loop']);
  4486.             $context array_intersect_key($context$_parent) + $_parent;
  4487.             // line 3413
  4488.             echo "                          </div>
  4489.                         </div>
  4490.                         ";
  4491.         }
  4492.         // line 3416
  4493.         echo "
  4494.                         ";
  4495.         // line 3417
  4496.         if (((((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3417$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3417$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3417$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3417$this->source); })()), "SaleType", [], "any"falsefalsefalse3417), "id", [], "any"falsefalsefalse3417), [=> 3=> 6]))) {
  4497.             // line 3418
  4498.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4499.                           <div class=\"rp-section-label\">奥行き";
  4500.             // line 3419
  4501.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3419$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3419$this->source); })()), "pd", [], "any"falsefalsefalse3419))) {
  4502.                 echo ": <span>";
  4503.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3419$this->source); })()), "pd", [], "any"falsefalsefalse3419), "html"nulltrue);
  4504.                 echo "</span>";
  4505.             }
  4506.             echo "</div>
  4507.                           <div class=\"opt-btn-group\">
  4508.                             ";
  4509.             // line 3421
  4510.             $context["idx"] = 0;
  4511.             // line 3422
  4512.             echo "                            ";
  4513.             $context['_parent'] = $context;
  4514.             $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3422$this->source); })()));
  4515.             foreach ($context['_seq'] as $context["_key"] => $context["pd"]) {
  4516.                 if ($context["pd"]) {
  4517.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3422$this->source); })()) + 1);
  4518.                     // line 3423
  4519.                     echo "                              <label class=\"opt-btn";
  4520.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3423$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3423$this->source); })()), "pd", [], "any"falsefalsefalse3423) == $context["pd"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3423$this->source); })())) == 1))) {
  4521.                         echo " is-selected";
  4522.                     }
  4523.                     echo "\"
  4524.                                      onclick=\"mitsumori_simulation_val('pd', '";
  4525.                     // line 3424
  4526.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pd"], "js"), "html"nulltrue);
  4527.                     echo "');\">
  4528.                                 <input type=\"radio\" name=\"pd\" id=\"pd_";
  4529.                     // line 3425
  4530.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3425$this->source); })()), "html"nulltrue);
  4531.                     echo "\" value=\"";
  4532.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  4533.                     echo "\"
  4534.                                        ";
  4535.                     // line 3426
  4536.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3426$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3426$this->source); })()), "pd", [], "any"falsefalsefalse3426) == $context["pd"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3426$this->source); })())) == 1))) {
  4537.                         echo "checked";
  4538.                     }
  4539.                     echo ">
  4540.                                 ";
  4541.                     // line 3427
  4542.                     echo twig_escape_filter($this->env$context["pd"], "html"nulltrue);
  4543.                     echo "
  4544.                               </label>
  4545.                             ";
  4546.                 }
  4547.             }
  4548.             $_parent $context['_parent'];
  4549.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd'], $context['_parent'], $context['loop']);
  4550.             $context array_intersect_key($context$_parent) + $_parent;
  4551.             // line 3430
  4552.             echo "                          </div>
  4553.                         </div>
  4554.                         ";
  4555.         }
  4556.         // line 3433
  4557.         echo "
  4558.                         ";
  4559.         // line 3436
  4560.         echo "                        ";
  4561.         if (((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3436$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3436$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3436$this->source); })())) != "")) && !twig_in_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3436$this->source); })()), "SaleType", [], "any"falsefalsefalse3436), "id", [], "any"falsefalsefalse3436), [=> 2=> 3=> 6]))) {
  4562.             // line 3437
  4563.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4564.                           <div class=\"rp-section-label\">高さ";
  4565.             // line 3438
  4566.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3438$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3438$this->source); })()), "ph", [], "any"falsefalsefalse3438))) {
  4567.                 echo ": <span>";
  4568.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3438$this->source); })()), "ph", [], "any"falsefalsefalse3438), "html"nulltrue);
  4569.                 echo "</span>";
  4570.             }
  4571.             echo "</div>
  4572.                           <div class=\"opt-btn-group\">
  4573.                             ";
  4574.             // line 3440
  4575.             $context["idx"] = 0;
  4576.             // line 3441
  4577.             echo "                            ";
  4578.             $context['_parent'] = $context;
  4579.             $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3441$this->source); })()));
  4580.             foreach ($context['_seq'] as $context["_key"] => $context["ph"]) {
  4581.                 if ($context["ph"]) {
  4582.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3441$this->source); })()) + 1);
  4583.                     // line 3442
  4584.                     echo "                              <label class=\"opt-btn";
  4585.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3442$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3442$this->source); })()), "ph", [], "any"falsefalsefalse3442) == $context["ph"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3442$this->source); })())) == 1))) {
  4586.                         echo " is-selected";
  4587.                     }
  4588.                     echo "\"
  4589.                                      onclick=\"mitsumori_simulation_val('ph', '";
  4590.                     // line 3443
  4591.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["ph"], "js"), "html"nulltrue);
  4592.                     echo "');\">
  4593.                                 <input type=\"radio\" name=\"ph\" id=\"ph_";
  4594.                     // line 3444
  4595.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3444$this->source); })()), "html"nulltrue);
  4596.                     echo "\" value=\"";
  4597.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  4598.                     echo "\"
  4599.                                        ";
  4600.                     // line 3445
  4601.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3445$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3445$this->source); })()), "ph", [], "any"falsefalsefalse3445) == $context["ph"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3445$this->source); })())) == 1))) {
  4602.                         echo "checked";
  4603.                     }
  4604.                     echo ">
  4605.                                 ";
  4606.                     // line 3446
  4607.                     echo twig_escape_filter($this->env$context["ph"], "html"nulltrue);
  4608.                     echo "
  4609.                               </label>
  4610.                             ";
  4611.                 }
  4612.             }
  4613.             $_parent $context['_parent'];
  4614.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph'], $context['_parent'], $context['loop']);
  4615.             $context array_intersect_key($context$_parent) + $_parent;
  4616.             // line 3449
  4617.             echo "                          </div>
  4618.                         </div>
  4619.                         ";
  4620.         }
  4621.         // line 3452
  4622.         echo "
  4623.                         ";
  4624.         // line 3454
  4625.         echo "                        ";
  4626.         if ((((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3454$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3454$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3454$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3454$this->source); })()), "SaleType", [], "any"falsefalsefalse3454), "id", [], "any"falsefalsefalse3454) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3454$this->source); })()), "SaleType", [], "any"falsefalsefalse3454), "id", [], "any"falsefalsefalse3454) != 2))) {
  4627.             // line 3455
  4628.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4629.                           <div class=\"rp-section-label\">素材";
  4630.             // line 3456
  4631.             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3456$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3456$this->source); })()), "pm", [], "any"falsefalsefalse3456))) {
  4632.                 echo ": <span>";
  4633.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3456$this->source); })()), "pm", [], "any"falsefalsefalse3456), "html"nulltrue);
  4634.                 echo "</span>";
  4635.             }
  4636.             echo "</div>
  4637.                           <div class=\"opt-btn-group\">
  4638.                             ";
  4639.             // line 3458
  4640.             $context["idx"] = 0;
  4641.             // line 3459
  4642.             echo "                            ";
  4643.             $context['_parent'] = $context;
  4644.             $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3459$this->source); })()));
  4645.             foreach ($context['_seq'] as $context["_key"] => $context["pm"]) {
  4646.                 if ($context["pm"]) {
  4647.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3459$this->source); })()) + 1);
  4648.                     // line 3460
  4649.                     echo "                              <label class=\"opt-btn";
  4650.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3460$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3460$this->source); })()), "pm", [], "any"falsefalsefalse3460) == $context["pm"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3460$this->source); })())) == 1))) {
  4651.                         echo " is-selected";
  4652.                     }
  4653.                     echo "\"
  4654.                                      onclick=\"mitsumori_simulation_val('pm', '";
  4655.                     // line 3461
  4656.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["pm"], "js"), "html"nulltrue);
  4657.                     echo "');\">
  4658.                                 <input type=\"radio\" name=\"pm\" id=\"pm_";
  4659.                     // line 3462
  4660.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3462$this->source); })()), "html"nulltrue);
  4661.                     echo "\" value=\"";
  4662.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  4663.                     echo "\"
  4664.                                        ";
  4665.                     // line 3463
  4666.                     if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3463$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3463$this->source); })()), "pm", [], "any"falsefalsefalse3463) == $context["pm"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3463$this->source); })())) == 1))) {
  4667.                         echo "checked";
  4668.                     }
  4669.                     echo ">
  4670.                                 ";
  4671.                     // line 3464
  4672.                     echo twig_escape_filter($this->env$context["pm"], "html"nulltrue);
  4673.                     echo "
  4674.                               </label>
  4675.                             ";
  4676.                 }
  4677.             }
  4678.             $_parent $context['_parent'];
  4679.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm'], $context['_parent'], $context['loop']);
  4680.             $context array_intersect_key($context$_parent) + $_parent;
  4681.             // line 3467
  4682.             echo "                          </div>
  4683.                         </div>
  4684.                         ";
  4685.         }
  4686.         // line 3470
  4687.         echo "
  4688.                         ";
  4689.         // line 3475
  4690.         echo "                        ";
  4691.         if (((((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3475$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3475$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3475$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3475$this->source); })()), "SaleType", [], "any"falsefalsefalse3475), "id", [], "any"falsefalsefalse3475) != 2)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3475$this->source); })()), "SaleType", [], "any"falsefalsefalse3475), "id", [], "any"falsefalsefalse3475) != 3)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3475$this->source); })()), "SaleType", [], "any"falsefalsefalse3475), "id", [], "any"falsefalsefalse3475) != 4))) {
  4692.             // line 3476
  4693.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4694.                           <div class=\"rp-section-label\">";
  4695.             // line 3477
  4696.             echo twig_escape_filter($this->env, (isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'3477$this->source); })()), "html"nulltrue);
  4697.             if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3477$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3477)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3477$this->source); })()), "option1", [], "any"falsefalsefalse3477))) {
  4698.                 echo ": <span>";
  4699.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3477$this->source); })()), "option1", [], "any"falsefalsefalse3477), "html"nulltrue);
  4700.                 echo "</span>";
  4701.             }
  4702.             echo "</div>
  4703.                           <div class=\"opt-btn-group\">
  4704.                             ";
  4705.             // line 3479
  4706.             $context["idx"] = 0;
  4707.             // line 3480
  4708.             echo "                            ";
  4709.             $context['_parent'] = $context;
  4710.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3480$this->source); })()));
  4711.             foreach ($context['_seq'] as $context["_key"] => $context["opt1"]) {
  4712.                 if ($context["opt1"]) {
  4713.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3480$this->source); })()) + 1);
  4714.                     // line 3481
  4715.                     echo "                              <label class=\"opt-btn";
  4716.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3481$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3481)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3481$this->source); })()), "option1", [], "any"falsefalsefalse3481) == $context["opt1"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3481$this->source); })())) == 1))) {
  4717.                         echo " is-selected";
  4718.                     }
  4719.                     echo "\"
  4720.                                      onclick=\"mitsumori_simulation_val('option1', '";
  4721.                     // line 3482
  4722.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt1"], "js"), "html"nulltrue);
  4723.                     echo "');\">
  4724.                                 <input type=\"radio\" name=\"option1\" id=\"option1_";
  4725.                     // line 3483
  4726.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3483$this->source); })()), "html"nulltrue);
  4727.                     echo "\" value=\"";
  4728.                     echo twig_escape_filter($this->env$context["opt1"], "html"nulltrue);
  4729.                     echo "\"
  4730.                                        ";
  4731.                     // line 3484
  4732.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3484$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3484)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3484$this->source); })()), "option1", [], "any"falsefalsefalse3484) == $context["opt1"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3484$this->source); })())) == 1))) {
  4733.                         echo "checked";
  4734.                     }
  4735.                     echo ">
  4736.                                 ";
  4737.                     // line 3485
  4738.                     echo twig_escape_filter($this->env$context["opt1"], "html"nulltrue);
  4739.                     echo "
  4740.                               </label>
  4741.                             ";
  4742.                 }
  4743.             }
  4744.             $_parent $context['_parent'];
  4745.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1'], $context['_parent'], $context['loop']);
  4746.             $context array_intersect_key($context$_parent) + $_parent;
  4747.             // line 3488
  4748.             echo "                          </div>
  4749.                         </div>
  4750.                         ";
  4751.         }
  4752.         // line 3491
  4753.         echo "
  4754.                         ";
  4755.         // line 3493
  4756.         echo "                        ";
  4757.         if ((((((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3493$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3493$this->source); })()))) && (twig_join_filter((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3493$this->source); })())) != "")) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3493$this->source); })()), "SaleType", [], "any"falsefalsefalse3493), "id", [], "any"falsefalsefalse3493) != 2)) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3493$this->source); })()), "SaleType", [], "any"falsefalsefalse3493), "id", [], "any"falsefalsefalse3493) != 3))) {
  4758.             // line 3494
  4759.             echo "                        <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  4760.                           <div class=\"rp-section-label\">";
  4761.             // line 3495
  4762.             echo twig_escape_filter($this->env, (isset($context["option2_label"]) || array_key_exists("option2_label"$context) ? $context["option2_label"] : (function () { throw new RuntimeError('Variable "option2_label" does not exist.'3495$this->source); })()), "html"nulltrue);
  4763.             if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3495$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3495)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3495$this->source); })()), "option2", [], "any"falsefalsefalse3495))) {
  4764.                 echo ": <span>";
  4765.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3495$this->source); })()), "option2", [], "any"falsefalsefalse3495), "html"nulltrue);
  4766.                 echo "</span>";
  4767.             }
  4768.             echo "</div>
  4769.                           <div class=\"opt-btn-group\">
  4770.                             ";
  4771.             // line 3497
  4772.             $context["idx"] = 0;
  4773.             // line 3498
  4774.             echo "                            ";
  4775.             $context['_parent'] = $context;
  4776.             $context['_seq'] = twig_ensure_traversable((isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3498$this->source); })()));
  4777.             foreach ($context['_seq'] as $context["_key"] => $context["opt2"]) {
  4778.                 if ($context["opt2"]) {
  4779.                     $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3498$this->source); })()) + 1);
  4780.                     // line 3499
  4781.                     echo "                              <label class=\"opt-btn";
  4782.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3499$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3499)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3499$this->source); })()), "option2", [], "any"falsefalsefalse3499) == $context["opt2"])) || (twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3499$this->source); })())) == 1))) {
  4783.                         echo " is-selected";
  4784.                     }
  4785.                     echo "\"
  4786.                                      onclick=\"mitsumori_simulation_val('option2', '";
  4787.                     // line 3500
  4788.                     echo twig_escape_filter($this->envtwig_escape_filter($this->env$context["opt2"], "js"), "html"nulltrue);
  4789.                     echo "');\">
  4790.                                 <input type=\"radio\" name=\"option2\" id=\"option2_";
  4791.                     // line 3501
  4792.                     echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3501$this->source); })()), "html"nulltrue);
  4793.                     echo "\" value=\"";
  4794.                     echo twig_escape_filter($this->env$context["opt2"], "html"nulltrue);
  4795.                     echo "\"
  4796.                                        ";
  4797.                     // line 3502
  4798.                     if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3502$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option2", [], "any"truetruefalse3502)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3502$this->source); })()), "option2", [], "any"falsefalsefalse3502) == $context["opt2"])) || (twig_length_filter($this->env, (isset($context["p_option2"]) || array_key_exists("p_option2"$context) ? $context["p_option2"] : (function () { throw new RuntimeError('Variable "p_option2" does not exist.'3502$this->source); })())) == 1))) {
  4799.                         echo "checked";
  4800.                     }
  4801.                     echo ">
  4802.                                 ";
  4803.                     // line 3503
  4804.                     echo twig_escape_filter($this->env$context["opt2"], "html"nulltrue);
  4805.                     echo "
  4806.                               </label>
  4807.                             ";
  4808.                 }
  4809.             }
  4810.             $_parent $context['_parent'];
  4811.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt2'], $context['_parent'], $context['loop']);
  4812.             $context array_intersect_key($context$_parent) + $_parent;
  4813.             // line 3506
  4814.             echo "                          </div>
  4815.                         </div>
  4816.                         ";
  4817.         }
  4818.         // line 3509
  4819.         echo "
  4820. \t\t\t\t\t\t<!-- 1: 施工見積(通常) → 幅/奥行/高さ/素材/カラーは上部の共通ブロックで表示済み -->
  4821. \t\t\t\t\t\t";
  4822.         // line 3511
  4823.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3511$this->source); })()), "SaleType", [], "any"falsefalsefalse3511), "id", [], "any"falsefalsefalse3511) == 1)) {
  4824.             // line 3512
  4825.             echo "\t\t\t\t\t\t";
  4826.         }
  4827.         // line 3513
  4828.         echo "
  4829. \t\t\t\t\t\t<!-- 2: 施工見積(補助金・窓) 複数タイプ追加対応 (2026-05) -->
  4830. \t\t\t\t\t\t";
  4831.         // line 3515
  4832.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3515$this->source); })()), "SaleType", [], "any"falsefalsefalse3515), "id", [], "any"falsefalsefalse3515) == 2)) {
  4833.             // line 3516
  4834.             echo "
  4835. \t\t\t\t\t\t\t";
  4836.             // line 3520
  4837.             echo "
  4838. \t\t\t\t\t\t\t";
  4839.             // line 3524
  4840.             echo "\t\t\t\t\t\t\t<style>
  4841. \t\t\t\t\t\t\t\t.ec-productRole__profile {
  4842. \t\t\t\t\t\t\t\t\toverflow: visible !important;
  4843. \t\t\t\t\t\t\t\t\tmax-height: none !important;
  4844. \t\t\t\t\t\t\t\t\theight: auto !important;
  4845. \t\t\t\t\t\t\t\t}
  4846. \t\t\t\t\t\t\t</style>
  4847. \t\t\t\t\t\t\t";
  4848.             // line 3533
  4849.             echo "\t\t\t\t\t\t\t";
  4850.             $context["housing_default"] = _twig_default_filter($this->extensions['Plugin\ProductField\Twig\Extension\EccubeExtension']->getProduct_field(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'3533$this->source); })()), "id", [], "any"falsefalsefalse3533), "住宅区分"), "戸建");
  4851.             // line 3534
  4852.             echo "\t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  4853. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  4854. \t\t\t\t\t\t\t    <strong>お住まいの種別を選択</strong>
  4855. \t\t\t\t\t\t\t    <small class=\"ms-2 text-muted\">補助金単価が変わります</small>
  4856. \t\t\t\t\t\t\t  </div>
  4857. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  4858. \t\t\t\t\t\t\t    <div class=\"opt-btn-group\" id=\"window-housing-type-group\">
  4859. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  4860. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"戸建\"
  4861. \t\t\t\t\t\t\t               ";
  4862.             // line 3543
  4863.             if (((isset($context["housing_default"]) || array_key_exists("housing_default"$context) ? $context["housing_default"] : (function () { throw new RuntimeError('Variable "housing_default" does not exist.'3543$this->source); })()) != "集合住宅")) {
  4864.                 echo "checked";
  4865.             }
  4866.             echo ">
  4867. \t\t\t\t\t\t\t        戸建住宅<small class=\"d-block text-muted\">(延床240㎡以下の非住宅含む)</small>
  4868. \t\t\t\t\t\t\t      </label>
  4869. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  4870. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"集合住宅\"
  4871. \t\t\t\t\t\t\t               ";
  4872.             // line 3548
  4873.             if (((isset($context["housing_default"]) || array_key_exists("housing_default"$context) ? $context["housing_default"] : (function () { throw new RuntimeError('Variable "housing_default" does not exist.'3548$this->source); })()) == "集合住宅")) {
  4874.                 echo "checked";
  4875.             }
  4876.             echo ">
  4877. \t\t\t\t\t\t\t        集合住宅<small class=\"d-block text-muted\">(低層・中高層/240㎡超の非住宅)</small>
  4878. \t\t\t\t\t\t\t      </label>
  4879. \t\t\t\t\t\t\t    </div>
  4880. \t\t\t\t\t\t\t  </div>
  4881. \t\t\t\t\t\t\t</div>
  4882. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  4883. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  4884. \t\t\t\t\t\t\t    <strong>窓タイプを選択(複数追加可・最大 20)</strong>
  4885. \t\t\t\t\t\t\t  </div>
  4886. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  4887. \t\t\t\t\t\t\t    <div id=\"window-types-container\"><!-- 動的に窓タイプブロックが追加される --></div>
  4888. \t\t\t\t\t\t\t    <div class=\"text-center mt-2\">
  4889. \t\t\t\t\t\t\t      <button type=\"button\" id=\"btn-add-window-type\" class=\"btn btn-outline-primary btn-sm\" onclick=\"addWindowType();\">+ 窓タイプを追加</button>
  4890. \t\t\t\t\t\t\t      <div class=\"small text-muted mt-1\">最大 20 タイプまで追加できます</div>
  4891. \t\t\t\t\t\t\t    </div>
  4892. \t\t\t\t\t\t\t  </div>
  4893. \t\t\t\t\t\t\t</div>
  4894. \t\t\t\t\t\t\t";
  4895.             // line 3569
  4896.             echo "\t\t\t\t\t\t\t<template id=\"window-type-template\">
  4897. \t\t\t\t\t\t\t  <div class=\"window-type-block\" data-type-idx=\"__IDX__\" style=\"border:1px solid #ddd;border-radius:6px;padding:10px;margin-bottom:10px;background:#fafafa;\">
  4898. \t\t\t\t\t\t\t    <div class=\"d-flex justify-content-between align-items-center mb-2\">
  4899. \t\t\t\t\t\t\t      <strong>窓タイプ <span class=\"wt-num\">__IDX__</span></strong>
  4900. \t\t\t\t\t\t\t      <button type=\"button\" class=\"btn btn-sm btn-outline-danger btn-remove-window-type\" onclick=\"removeWindowType(this);\">× 削除</button>
  4901. \t\t\t\t\t\t\t    </div>
  4902. \t\t\t\t\t\t\t    ";
  4903.             // line 3577
  4904.             echo "\t\t\t\t\t\t\t    ";
  4905.             if ((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3577$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3577$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3577$this->source); })())) != ""))) {
  4906.                 // line 3578
  4907.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  4908. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓タイプ</div>
  4909. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  4910. \t\t\t\t\t\t\t        ";
  4911.                 // line 3581
  4912.                 $context['_parent'] = $context;
  4913.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3581$this->source); })()));
  4914.                 foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  4915.                     if ($context["v"]) {
  4916.                         // line 3582
  4917.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn\">
  4918. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_subtype___IDX__\" value=\"";
  4919.                         // line 3583
  4920.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  4921.                         echo "\" data-axis=\"subtype\" onchange=\"onWindowTypeAxisChange(this);\">
  4922. \t\t\t\t\t\t\t            ";
  4923.                         // line 3584
  4924.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  4925.                         echo "
  4926. \t\t\t\t\t\t\t          </label>
  4927. \t\t\t\t\t\t\t        ";
  4928.                     }
  4929.                 }
  4930.                 $_parent $context['_parent'];
  4931.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  4932.                 $context array_intersect_key($context$_parent) + $_parent;
  4933.                 // line 3587
  4934.                 echo "\t\t\t\t\t\t\t      </div>
  4935. \t\t\t\t\t\t\t    </div>
  4936. \t\t\t\t\t\t\t    ";
  4937.             }
  4938.             // line 3590
  4939.             echo "
  4940. \t\t\t\t\t\t\t    ";
  4941.             // line 3592
  4942.             echo "\t\t\t\t\t\t\t    ";
  4943.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3592$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3592$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3592$this->source); })())) != ""))) {
  4944.                 // line 3593
  4945.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  4946. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">幅</div>
  4947. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  4948. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_pw___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  4949. \t\t\t\t\t\t\t               placeholder=\"例 1750\" data-axis=\"pw\" data-unit=\"mm\"
  4950. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  4951. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  4952. \t\t\t\t\t\t\t      </div>
  4953. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応幅: 〜";
  4954.                 // line 3601
  4955.                 echo twig_escape_filter($this->env_twig_default_filter(twig_last($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3601$this->source); })())), ""), "html"nulltrue);
  4956.                 echo "(";
  4957.                 echo twig_escape_filter($this->envtwig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3601$this->source); })())), "html"nulltrue);
  4958.                 echo " 段階の価格帯から自動選択)</small>
  4959. \t\t\t\t\t\t\t    </div>
  4960. \t\t\t\t\t\t\t    ";
  4961.             }
  4962.             // line 3604
  4963.             echo "
  4964. \t\t\t\t\t\t\t    ";
  4965.             // line 3606
  4966.             echo "\t\t\t\t\t\t\t    ";
  4967.             if ((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3606$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3606$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3606$this->source); })())) != ""))) {
  4968.                 // line 3607
  4969.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  4970. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">高さ</div>
  4971. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  4972. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_ph___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  4973. \t\t\t\t\t\t\t               placeholder=\"例 1200\" data-axis=\"ph\" data-unit=\"mm\"
  4974. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  4975. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  4976. \t\t\t\t\t\t\t      </div>
  4977. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応高さ: 〜";
  4978.                 // line 3615
  4979.                 echo twig_escape_filter($this->env_twig_default_filter(twig_last($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3615$this->source); })())), ""), "html"nulltrue);
  4980.                 echo "(";
  4981.                 echo twig_escape_filter($this->envtwig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3615$this->source); })())), "html"nulltrue);
  4982.                 echo " 段階の価格帯から自動選択)</small>
  4983. \t\t\t\t\t\t\t    </div>
  4984. \t\t\t\t\t\t\t    ";
  4985.             }
  4986.             // line 3618
  4987.             echo "
  4988. \t\t\t\t\t\t\t    ";
  4989.             // line 3620
  4990.             echo "\t\t\t\t\t\t\t    ";
  4991.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3620$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3620$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3620$this->source); })())) != ""))) {
  4992.                 // line 3621
  4993.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  4994. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">ガラスタイプ</div>
  4995. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  4996. \t\t\t\t\t\t\t        ";
  4997.                 // line 3624
  4998.                 $context['_parent'] = $context;
  4999.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3624$this->source); })()));
  5000.                 foreach ($context['_seq'] as $context["_key"] => $context["v"]) {
  5001.                     if ($context["v"]) {
  5002.                         // line 3625
  5003.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn\">
  5004. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pm___IDX__\" value=\"";
  5005.                         // line 3626
  5006.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5007.                         echo "\" data-axis=\"pm\" onchange=\"onWindowTypeAxisChange(this);\">
  5008. \t\t\t\t\t\t\t            ";
  5009.                         // line 3627
  5010.                         echo twig_escape_filter($this->env$context["v"], "html"nulltrue);
  5011.                         echo "
  5012. \t\t\t\t\t\t\t          </label>
  5013. \t\t\t\t\t\t\t        ";
  5014.                     }
  5015.                 }
  5016.                 $_parent $context['_parent'];
  5017.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['v'], $context['_parent'], $context['loop']);
  5018.                 $context array_intersect_key($context$_parent) + $_parent;
  5019.                 // line 3630
  5020.                 echo "\t\t\t\t\t\t\t      </div>
  5021. \t\t\t\t\t\t\t      <small class=\"text-muted\">「<span style=\"color:#2e7d32;font-weight:bold;\">補助金対象</span>」が付いたガラスは、先進的窓リノベ補助金の対象です。</small>
  5022. \t\t\t\t\t\t\t    </div>
  5023. \t\t\t\t\t\t\t    ";
  5024.             }
  5025.             // line 3634
  5026.             echo "
  5027. \t\t\t\t\t\t\t    ";
  5028.             // line 3636
  5029.             echo "\t\t\t\t\t\t\t    ";
  5030.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3636$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3636$this->source); })())))) {
  5031.                 // line 3637
  5032.                 echo "\t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  5033. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓枠カラー</div>
  5034. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  5035. \t\t\t\t\t\t\t        ";
  5036.                 // line 3640
  5037.                 $context['_parent'] = $context;
  5038.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3640$this->source); })()));
  5039.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  5040.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3640))) {
  5041.                         // line 3641
  5042.                         echo "\t\t\t\t\t\t\t          ";
  5043.                         $context["has_img"] = (twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"truetruefalse3641) &&  !twig_test_empty(twig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3641)));
  5044.                         // line 3642
  5045.                         echo "\t\t\t\t\t\t\t          <label class=\"opt-btn";
  5046.                         if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3642$this->source); })())) {
  5047.                             echo " opt-btn--with-image";
  5048.                         }
  5049.                         echo "\">
  5050. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pc___IDX__\" value=\"";
  5051.                         // line 3643
  5052.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3643), "html"nulltrue);
  5053.                         echo "\" data-axis=\"pc\" onchange=\"onWindowTypeAxisChange(this);\">
  5054. \t\t\t\t\t\t\t            ";
  5055.                         // line 3644
  5056.                         if ((isset($context["has_img"]) || array_key_exists("has_img"$context) ? $context["has_img"] : (function () { throw new RuntimeError('Variable "has_img" does not exist.'3644$this->source); })())) {
  5057.                             // line 3645
  5058.                             echo "\t\t\t\t\t\t\t              <img src=\"";
  5059.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "img", [], "array"falsefalsefalse3645), "html"nulltrue);
  5060.                             echo "\" alt=\"";
  5061.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3645), "html"nulltrue);
  5062.                             echo "\" class=\"opt-btn__img\"
  5063. \t\t\t\t\t\t\t                   onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  5064. \t\t\t\t\t\t\t              <span class=\"opt-btn__name\">";
  5065.                             // line 3647
  5066.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3647), "html"nulltrue);
  5067.                             echo "</span>
  5068. \t\t\t\t\t\t\t            ";
  5069.                         } else {
  5070.                             // line 3649
  5071.                             echo "\t\t\t\t\t\t\t              ";
  5072.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3649), "html"nulltrue);
  5073.                             echo "
  5074. \t\t\t\t\t\t\t            ";
  5075.                         }
  5076.                         // line 3651
  5077.                         echo "\t\t\t\t\t\t\t          </label>
  5078. \t\t\t\t\t\t\t        ";
  5079.                     }
  5080.                 }
  5081.                 $_parent $context['_parent'];
  5082.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  5083.                 $context array_intersect_key($context$_parent) + $_parent;
  5084.                 // line 3653
  5085.                 echo "\t\t\t\t\t\t\t      </div>
  5086. \t\t\t\t\t\t\t    </div>
  5087. \t\t\t\t\t\t\t    ";
  5088.             }
  5089.             // line 3656
  5090.             echo "
  5091. \t\t\t\t\t\t\t    ";
  5092.             // line 3658
  5093.             echo "\t\t\t\t\t\t\t    <div class=\"form-group row mt-2 align-items-center\">
  5094. \t\t\t\t\t\t\t      <label class=\"col-4 col-form-label\">セット数</label>
  5095. \t\t\t\t\t\t\t      <div class=\"col-4\">
  5096. \t\t\t\t\t\t\t        <div class=\"input-group\">
  5097. \t\t\t\t\t\t\t          <input type=\"number\" name=\"wt_setqty___IDX__\" class=\"form-control wt-input-setqty\" value=\"1\" min=\"1\" max=\"99\" data-axis=\"setqty\" onchange=\"onWindowTypeAxisChange(this);\">
  5098. \t\t\t\t\t\t\t          <span class=\"input-group-text\">セット</span>
  5099. \t\t\t\t\t\t\t        </div>
  5100. \t\t\t\t\t\t\t      </div>
  5101. \t\t\t\t\t\t\t      <div class=\"col-4 text-end\">
  5102. \t\t\t\t\t\t\t        <small class=\"text-muted\">補助金額<br><span class=\"wt-subsidy-amount\">―</span> 円</small>
  5103. \t\t\t\t\t\t\t      </div>
  5104. \t\t\t\t\t\t\t    </div>
  5105. \t\t\t\t\t\t\t  </div>
  5106. \t\t\t\t\t\t\t</template>
  5107. \t\t\t\t\t\t\t";
  5108.             // line 3674
  5109.             echo "\t\t\t\t\t\t\t<script>
  5110. \t\t\t\t\t\t\t(function() {
  5111. \t\t\t\t\t\t\t\tvar MAX_WINDOW_TYPES = 20;
  5112. \t\t\t\t\t\t\t\tfunction addWindowType() {
  5113. \t\t\t\t\t\t\t\t\tvar container = document.getElementById('window-types-container');
  5114. \t\t\t\t\t\t\t\t\tif (!container) return;
  5115. \t\t\t\t\t\t\t\t\tvar existing = container.querySelectorAll('.window-type-block');
  5116. \t\t\t\t\t\t\t\t\tif (existing.length >= MAX_WINDOW_TYPES) return;
  5117. \t\t\t\t\t\t\t\t\tvar newIdx = existing.length + 1;
  5118. \t\t\t\t\t\t\t\t\tvar tpl = document.getElementById('window-type-template');
  5119. \t\t\t\t\t\t\t\t\tif (!tpl) return;
  5120. \t\t\t\t\t\t\t\t\t// <template> の innerHTML を取り出して __IDX__ を新規連番に置換し、要素化して append.
  5121. \t\t\t\t\t\t\t\t\tvar html = tpl.innerHTML.replace(/__IDX__/g, String(newIdx));
  5122. \t\t\t\t\t\t\t\t\tvar wrapper = document.createElement('div');
  5123. \t\t\t\t\t\t\t\t\twrapper.innerHTML = html.trim();
  5124. \t\t\t\t\t\t\t\t\tvar block = wrapper.firstChild;
  5125. \t\t\t\t\t\t\t\t\tcontainer.appendChild(block);
  5126. \t\t\t\t\t\t\t\t\tdecorateSubsidyGlass(block);
  5127. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  5128. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5129. \t\t\t\t\t\t\t\t}
  5130. \t\t\t\t\t\t\t\t// 補助金対象ガラスの選択肢に「補助金対象」バッジ + 緑枠を付与する.
  5131. \t\t\t\t\t\t\t\t// 判定は calc script 側の window.glassYieldsSubsidy に委譲 (ロジック二重化を避ける)。
  5132. \t\t\t\t\t\t\t\tfunction decorateSubsidyGlass(block) {
  5133. \t\t\t\t\t\t\t\t\tif (!block || typeof window.glassYieldsSubsidy !== 'function') return;
  5134. \t\t\t\t\t\t\t\t\tvar radios = block.querySelectorAll('input[data-axis=\"pm\"]');
  5135. \t\t\t\t\t\t\t\t\tradios.forEach(function(inp) {
  5136. \t\t\t\t\t\t\t\t\t\tvar label = inp.closest('.opt-btn');
  5137. \t\t\t\t\t\t\t\t\t\tif (!label || label.querySelector('.opt-btn__subsidy-badge')) return;
  5138. \t\t\t\t\t\t\t\t\t\tif (window.glassYieldsSubsidy(inp.value)) {
  5139. \t\t\t\t\t\t\t\t\t\t\tlabel.classList.add('opt-btn--subsidy');
  5140. \t\t\t\t\t\t\t\t\t\t\tvar badge = document.createElement('span');
  5141. \t\t\t\t\t\t\t\t\t\t\tbadge.className = 'opt-btn__subsidy-badge';
  5142. \t\t\t\t\t\t\t\t\t\t\tbadge.textContent = '補助金対象';
  5143. \t\t\t\t\t\t\t\t\t\t\tlabel.appendChild(badge);
  5144. \t\t\t\t\t\t\t\t\t\t}
  5145. \t\t\t\t\t\t\t\t\t});
  5146. \t\t\t\t\t\t\t\t}
  5147. \t\t\t\t\t\t\t\tfunction removeWindowType(btn) {
  5148. \t\t\t\t\t\t\t\t\tvar block = btn.closest('.window-type-block');
  5149. \t\t\t\t\t\t\t\t\tif (!block) return;
  5150. \t\t\t\t\t\t\t\t\tblock.remove();
  5151. \t\t\t\t\t\t\t\t\treindexBlocks();
  5152. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  5153. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5154. \t\t\t\t\t\t\t\t}
  5155. \t\t\t\t\t\t\t\tfunction updateRemoveButtonVisibility() {
  5156. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  5157. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b) {
  5158. \t\t\t\t\t\t\t\t\t\tvar btn = b.querySelector('.btn-remove-window-type');
  5159. \t\t\t\t\t\t\t\t\t\tif (btn) btn.style.display = blocks.length > 1 ? '' : 'none';
  5160. \t\t\t\t\t\t\t\t\t});
  5161. \t\t\t\t\t\t\t\t}
  5162. \t\t\t\t\t\t\t\tfunction reindexBlocks() {
  5163. \t\t\t\t\t\t\t\t\t// ブロック削除後に 1 から振り直し. input[name] の末尾 _N も書き換える.
  5164. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  5165. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b, i) {
  5166. \t\t\t\t\t\t\t\t\t\tvar n = i + 1;
  5167. \t\t\t\t\t\t\t\t\t\tb.setAttribute('data-type-idx', String(n));
  5168. \t\t\t\t\t\t\t\t\t\tvar numSpan = b.querySelector('.wt-num');
  5169. \t\t\t\t\t\t\t\t\t\tif (numSpan) numSpan.textContent = String(n);
  5170. \t\t\t\t\t\t\t\t\t\tb.querySelectorAll('input[name]').forEach(function(inp) {
  5171. \t\t\t\t\t\t\t\t\t\t\tinp.name = inp.name.replace(/_\\d+\$/, '_' + n);
  5172. \t\t\t\t\t\t\t\t\t\t});
  5173. \t\t\t\t\t\t\t\t\t});
  5174. \t\t\t\t\t\t\t\t}
  5175. \t\t\t\t\t\t\t\t// 軸変更イベント. recalcAll が定義されていれば再計算 (task 2 で実装).
  5176. \t\t\t\t\t\t\t\twindow.onWindowTypeAxisChange = function() {
  5177. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5178. \t\t\t\t\t\t\t\t};
  5179. \t\t\t\t\t\t\t\twindow.addWindowType = addWindowType;
  5180. \t\t\t\t\t\t\t\twindow.removeWindowType = removeWindowType;
  5181. \t\t\t\t\t\t\t\t// 隠し radio(opacity:0/pointer-events:none) を label で包む opt-btn は iOS で初回タップの
  5182. \t\t\t\t\t\t\t\t// change が不発になりやすい。窓タイプ/住宅区分は label に onclick が無く change 依存だった
  5183. \t\t\t\t\t\t\t\t// ため「2回タッチ/選択できない」が発生。click は確実に発火するので委譲 click で選択状態・
  5184. \t\t\t\t\t\t\t\t// is-selected・再計算を行う(JSで複製される窓タイプにも委譲で対応)。
  5185. \t\t\t\t\t\t\t\tdocument.addEventListener('click', function(ev) {
  5186. \t\t\t\t\t\t\t\t\tif (!ev.target || !ev.target.closest) return;
  5187. \t\t\t\t\t\t\t\t\tvar label = ev.target.closest('.opt-btn');
  5188. \t\t\t\t\t\t\t\t\tif (!label) return;
  5189. \t\t\t\t\t\t\t\t\tif (!label.closest('#window-types-container') && !label.closest('#window-housing-type-group')) return;
  5190. \t\t\t\t\t\t\t\t\tvar input = label.querySelector('input[type=\"radio\"]');
  5191. \t\t\t\t\t\t\t\t\tif (!input || input.disabled) return;
  5192. \t\t\t\t\t\t\t\t\tinput.checked = true;
  5193. \t\t\t\t\t\t\t\t\tvar nm = input.getAttribute('name');
  5194. \t\t\t\t\t\t\t\t\tif (nm) {
  5195. \t\t\t\t\t\t\t\t\t\tdocument.querySelectorAll('input[name=\"' + nm + '\"]').forEach(function(i) {
  5196. \t\t\t\t\t\t\t\t\t\t\tvar l = i.closest('.opt-btn');
  5197. \t\t\t\t\t\t\t\t\t\t\tif (l) l.classList.toggle('is-selected', i.checked);
  5198. \t\t\t\t\t\t\t\t\t\t});
  5199. \t\t\t\t\t\t\t\t\t}
  5200. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5201. \t\t\t\t\t\t\t\t});
  5202. \t\t\t\t\t\t\t\t// 初期表示で 1 ブロック追加 + 住宅区分ラジオの change で再計算.
  5203. \t\t\t\t\t\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
  5204. \t\t\t\t\t\t\t\t\tif (document.querySelector('#window-types-container')) {
  5205. \t\t\t\t\t\t\t\t\t\taddWindowType();
  5206. \t\t\t\t\t\t\t\t\t}
  5207. \t\t\t\t\t\t\t\t\tvar housingInputs = document.querySelectorAll('input[name=\"window_housing_type\"]');
  5208. \t\t\t\t\t\t\t\t\tvar syncHousingSelectedClass = function() {
  5209. \t\t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  5210. \t\t\t\t\t\t\t\t\t\t\tvar lbl = el.closest('.opt-btn');
  5211. \t\t\t\t\t\t\t\t\t\t\tif (!lbl) return;
  5212. \t\t\t\t\t\t\t\t\t\t\tif (el.checked) lbl.classList.add('is-selected');
  5213. \t\t\t\t\t\t\t\t\t\t\telse            lbl.classList.remove('is-selected');
  5214. \t\t\t\t\t\t\t\t\t\t});
  5215. \t\t\t\t\t\t\t\t\t};
  5216. \t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  5217. \t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  5218. \t\t\t\t\t\t\t\t\t\tel.addEventListener('change', function() {
  5219. \t\t\t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  5220. \t\t\t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  5221. \t\t\t\t\t\t\t\t\t\t});
  5222. \t\t\t\t\t\t\t\t\t});
  5223. \t\t\t\t\t\t\t\t});
  5224. \t\t\t\t\t\t\t})();
  5225. \t\t\t\t\t\t\t</script>
  5226. \t\t\t\t\t\t";
  5227.         }
  5228.         // line 3802
  5229.         echo "
  5230. \t\t\t\t\t\t<!-- 3: 施工見積(物置・ゴミステーション) -->
  5231. \t\t\t\t\t\t";
  5232.         // line 3804
  5233.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3804$this->source); })()), "SaleType", [], "any"falsefalsefalse3804), "id", [], "any"falsefalsefalse3804) == 3)) {
  5234.             // line 3805
  5235.             echo "
  5236. \t\t\t\t\t\t\t";
  5237.             // line 3807
  5238.             echo "\t\t\t\t\t\t\t";
  5239.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3807$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3807$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3807$this->source); })())) != ""))) {
  5240.                 // line 3808
  5241.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5242. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">幅";
  5243.                 // line 3809
  5244.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3809$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3809$this->source); })()), "pw", [], "any"falsefalsefalse3809))) {
  5245.                     echo ": <span>";
  5246.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3809$this->source); })()), "pw", [], "any"falsefalsefalse3809), "html"nulltrue);
  5247.                     echo "</span>";
  5248.                 }
  5249.                 echo "</div>
  5250. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5251. \t\t\t\t\t\t\t    ";
  5252.                 // line 3811
  5253.                 $context["idx"] = 0;
  5254.                 // line 3812
  5255.                 echo "\t\t\t\t\t\t\t    ";
  5256.                 $context['_parent'] = $context;
  5257.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3812$this->source); })()));
  5258.                 foreach ($context['_seq'] as $context["_key"] => $context["pw_val"]) {
  5259.                     if ($context["pw_val"]) {
  5260.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3812$this->source); })()) + 1);
  5261.                         // line 3813
  5262.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5263.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3813$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3813$this->source); })()), "pw", [], "any"falsefalsefalse3813) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3813$this->source); })())) == 1))) {
  5264.                             echo " is-selected";
  5265.                         }
  5266.                         echo "\"
  5267. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw3_";
  5268.                         // line 3814
  5269.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3814$this->source); })()), "html"nulltrue);
  5270.                         echo "');\">
  5271. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw3_";
  5272.                         // line 3815
  5273.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3815$this->source); })()), "html"nulltrue);
  5274.                         echo "\" value=\"";
  5275.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5276.                         echo "\"
  5277. \t\t\t\t\t\t\t               ";
  5278.                         // line 3816
  5279.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3816$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3816$this->source); })()), "pw", [], "any"falsefalsefalse3816) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'3816$this->source); })())) == 1))) {
  5280.                             echo "checked";
  5281.                         }
  5282.                         echo ">
  5283. \t\t\t\t\t\t\t        ";
  5284.                         // line 3817
  5285.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5286.                         echo "
  5287. \t\t\t\t\t\t\t      </label>
  5288. \t\t\t\t\t\t\t    ";
  5289.                     }
  5290.                 }
  5291.                 $_parent $context['_parent'];
  5292.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw_val'], $context['_parent'], $context['loop']);
  5293.                 $context array_intersect_key($context$_parent) + $_parent;
  5294.                 // line 3820
  5295.                 echo "\t\t\t\t\t\t\t  </div>
  5296. \t\t\t\t\t\t\t</div>
  5297. \t\t\t\t\t\t\t";
  5298.             }
  5299.             // line 3823
  5300.             echo "
  5301. \t\t\t\t\t\t\t";
  5302.             // line 3824
  5303.             if ((((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3824$this->source); })()) && twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3824$this->source); })()))) && (twig_join_filter((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3824$this->source); })())) != ""))) {
  5304.                 // line 3825
  5305.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5306. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">奥行き";
  5307.                 // line 3826
  5308.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3826$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3826$this->source); })()), "pd", [], "any"falsefalsefalse3826))) {
  5309.                     echo ": <span>";
  5310.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3826$this->source); })()), "pd", [], "any"falsefalsefalse3826), "html"nulltrue);
  5311.                     echo "</span>";
  5312.                 }
  5313.                 echo "</div>
  5314. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5315. \t\t\t\t\t\t\t    ";
  5316.                 // line 3828
  5317.                 $context["idx"] = 0;
  5318.                 // line 3829
  5319.                 echo "\t\t\t\t\t\t\t    ";
  5320.                 $context['_parent'] = $context;
  5321.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3829$this->source); })()));
  5322.                 foreach ($context['_seq'] as $context["_key"] => $context["pd_val"]) {
  5323.                     if ($context["pd_val"]) {
  5324.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3829$this->source); })()) + 1);
  5325.                         // line 3830
  5326.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5327.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3830$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3830$this->source); })()), "pd", [], "any"falsefalsefalse3830) == $context["pd_val"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3830$this->source); })())) == 1))) {
  5328.                             echo " is-selected";
  5329.                         }
  5330.                         echo "\"
  5331. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pd','pd3_";
  5332.                         // line 3831
  5333.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3831$this->source); })()), "html"nulltrue);
  5334.                         echo "');\">
  5335. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pd\" id=\"pd3_";
  5336.                         // line 3832
  5337.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3832$this->source); })()), "html"nulltrue);
  5338.                         echo "\" value=\"";
  5339.                         echo twig_escape_filter($this->env$context["pd_val"], "html"nulltrue);
  5340.                         echo "\"
  5341. \t\t\t\t\t\t\t               ";
  5342.                         // line 3833
  5343.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3833$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3833$this->source); })()), "pd", [], "any"falsefalsefalse3833) == $context["pd_val"])) || (twig_length_filter($this->env, (isset($context["p_d"]) || array_key_exists("p_d"$context) ? $context["p_d"] : (function () { throw new RuntimeError('Variable "p_d" does not exist.'3833$this->source); })())) == 1))) {
  5344.                             echo "checked";
  5345.                         }
  5346.                         echo ">
  5347. \t\t\t\t\t\t\t        ";
  5348.                         // line 3834
  5349.                         echo twig_escape_filter($this->env$context["pd_val"], "html"nulltrue);
  5350.                         echo "
  5351. \t\t\t\t\t\t\t      </label>
  5352. \t\t\t\t\t\t\t    ";
  5353.                     }
  5354.                 }
  5355.                 $_parent $context['_parent'];
  5356.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pd_val'], $context['_parent'], $context['loop']);
  5357.                 $context array_intersect_key($context$_parent) + $_parent;
  5358.                 // line 3837
  5359.                 echo "\t\t\t\t\t\t\t  </div>
  5360. \t\t\t\t\t\t\t</div>
  5361. \t\t\t\t\t\t\t";
  5362.             }
  5363.             // line 3840
  5364.             echo "
  5365. \t\t\t\t\t\t\t";
  5366.             // line 3841
  5367.             if ((((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3841$this->source); })()) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3841$this->source); })()))) && (twig_join_filter((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3841$this->source); })())) != ""))) {
  5368.                 // line 3842
  5369.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5370. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">高さ";
  5371.                 // line 3843
  5372.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3843$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3843$this->source); })()), "ph", [], "any"falsefalsefalse3843))) {
  5373.                     echo ": <span>";
  5374.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3843$this->source); })()), "ph", [], "any"falsefalsefalse3843), "html"nulltrue);
  5375.                     echo "</span>";
  5376.                 }
  5377.                 echo "</div>
  5378. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5379. \t\t\t\t\t\t\t    ";
  5380.                 // line 3845
  5381.                 $context["idx"] = 0;
  5382.                 // line 3846
  5383.                 echo "\t\t\t\t\t\t\t    ";
  5384.                 $context['_parent'] = $context;
  5385.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3846$this->source); })()));
  5386.                 foreach ($context['_seq'] as $context["_key"] => $context["ph_val"]) {
  5387.                     if ($context["ph_val"]) {
  5388.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3846$this->source); })()) + 1);
  5389.                         // line 3847
  5390.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5391.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3847$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3847$this->source); })()), "ph", [], "any"falsefalsefalse3847) == $context["ph_val"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3847$this->source); })())) == 1))) {
  5392.                             echo " is-selected";
  5393.                         }
  5394.                         echo "\"
  5395. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('ph','ph3_";
  5396.                         // line 3848
  5397.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3848$this->source); })()), "html"nulltrue);
  5398.                         echo "');\">
  5399. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"ph\" id=\"ph3_";
  5400.                         // line 3849
  5401.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3849$this->source); })()), "html"nulltrue);
  5402.                         echo "\" value=\"";
  5403.                         echo twig_escape_filter($this->env$context["ph_val"], "html"nulltrue);
  5404.                         echo "\"
  5405. \t\t\t\t\t\t\t               ";
  5406.                         // line 3850
  5407.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3850$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3850$this->source); })()), "ph", [], "any"falsefalsefalse3850) == $context["ph_val"])) || (twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'3850$this->source); })())) == 1))) {
  5408.                             echo "checked";
  5409.                         }
  5410.                         echo ">
  5411. \t\t\t\t\t\t\t        ";
  5412.                         // line 3851
  5413.                         echo twig_escape_filter($this->env$context["ph_val"], "html"nulltrue);
  5414.                         echo "
  5415. \t\t\t\t\t\t\t      </label>
  5416. \t\t\t\t\t\t\t    ";
  5417.                     }
  5418.                 }
  5419.                 $_parent $context['_parent'];
  5420.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ph_val'], $context['_parent'], $context['loop']);
  5421.                 $context array_intersect_key($context$_parent) + $_parent;
  5422.                 // line 3854
  5423.                 echo "\t\t\t\t\t\t\t  </div>
  5424. \t\t\t\t\t\t\t</div>
  5425. \t\t\t\t\t\t\t";
  5426.             }
  5427.             // line 3857
  5428.             echo "
  5429. \t\t\t\t\t\t\t";
  5430.             // line 3859
  5431.             echo "\t\t\t\t\t\t\t";
  5432.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3859$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3859$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3859$this->source); })())) != ""))) {
  5433.                 // line 3860
  5434.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5435. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">棚タイプ <small class=\"text-muted\">(間仕切り仕様)</small>";
  5436.                 // line 3861
  5437.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3861$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3861$this->source); })()), "pm", [], "any"falsefalsefalse3861))) {
  5438.                     echo ": <span>";
  5439.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3861$this->source); })()), "pm", [], "any"falsefalsefalse3861), "html"nulltrue);
  5440.                     echo "</span>";
  5441.                 }
  5442.                 echo "</div>
  5443. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5444. \t\t\t\t\t\t\t    ";
  5445.                 // line 3863
  5446.                 $context["idx"] = 0;
  5447.                 // line 3864
  5448.                 echo "\t\t\t\t\t\t\t    ";
  5449.                 $context['_parent'] = $context;
  5450.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3864$this->source); })()));
  5451.                 foreach ($context['_seq'] as $context["_key"] => $context["pm_val"]) {
  5452.                     if ($context["pm_val"]) {
  5453.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3864$this->source); })()) + 1);
  5454.                         // line 3865
  5455.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5456.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3865$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3865$this->source); })()), "pm", [], "any"falsefalsefalse3865) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3865$this->source); })())) == 1))) {
  5457.                             echo " is-selected";
  5458.                         }
  5459.                         echo "\"
  5460. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm3_";
  5461.                         // line 3866
  5462.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3866$this->source); })()), "html"nulltrue);
  5463.                         echo "');\">
  5464. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm3_";
  5465.                         // line 3867
  5466.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3867$this->source); })()), "html"nulltrue);
  5467.                         echo "\" value=\"";
  5468.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  5469.                         echo "\"
  5470. \t\t\t\t\t\t\t               ";
  5471.                         // line 3868
  5472.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3868$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3868$this->source); })()), "pm", [], "any"falsefalsefalse3868) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'3868$this->source); })())) == 1))) {
  5473.                             echo "checked";
  5474.                         }
  5475.                         echo ">
  5476. \t\t\t\t\t\t\t        ";
  5477.                         // line 3869
  5478.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  5479.                         echo "
  5480. \t\t\t\t\t\t\t      </label>
  5481. \t\t\t\t\t\t\t    ";
  5482.                     }
  5483.                 }
  5484.                 $_parent $context['_parent'];
  5485.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm_val'], $context['_parent'], $context['loop']);
  5486.                 $context array_intersect_key($context$_parent) + $_parent;
  5487.                 // line 3872
  5488.                 echo "\t\t\t\t\t\t\t  </div>
  5489. \t\t\t\t\t\t\t</div>
  5490. \t\t\t\t\t\t\t";
  5491.             }
  5492.             // line 3875
  5493.             echo "
  5494. \t\t\t\t\t\t\t";
  5495.             // line 3877
  5496.             echo "\t\t\t\t\t\t\t";
  5497.             if ((((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3877$this->source); })()) && twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3877$this->source); })()))) && (twig_join_filter((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3877$this->source); })())) != ""))) {
  5498.                 // line 3878
  5499.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5500. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">";
  5501.                 // line 3879
  5502.                 echo twig_escape_filter($this->env, (isset($context["option1_label"]) || array_key_exists("option1_label"$context) ? $context["option1_label"] : (function () { throw new RuntimeError('Variable "option1_label" does not exist.'3879$this->source); })()), "html"nulltrue);
  5503.                 if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3879$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3879)) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3879$this->source); })()), "option1", [], "any"falsefalsefalse3879))) {
  5504.                     echo ": <span>";
  5505.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3879$this->source); })()), "option1", [], "any"falsefalsefalse3879), "html"nulltrue);
  5506.                     echo "</span>";
  5507.                 }
  5508.                 echo "</div>
  5509. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5510. \t\t\t\t\t\t\t    ";
  5511.                 // line 3881
  5512.                 $context["idx"] = 0;
  5513.                 // line 3882
  5514.                 echo "\t\t\t\t\t\t\t    ";
  5515.                 $context['_parent'] = $context;
  5516.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3882$this->source); })()));
  5517.                 foreach ($context['_seq'] as $context["_key"] => $context["opt1_val"]) {
  5518.                     if ($context["opt1_val"]) {
  5519.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3882$this->source); })()) + 1);
  5520.                         // line 3883
  5521.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5522.                         if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3883$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3883)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3883$this->source); })()), "option1", [], "any"falsefalsefalse3883) == $context["opt1_val"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3883$this->source); })())) == 1))) {
  5523.                             echo " is-selected";
  5524.                         }
  5525.                         echo "\"
  5526. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('option1','option1_3_";
  5527.                         // line 3884
  5528.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3884$this->source); })()), "html"nulltrue);
  5529.                         echo "');\">
  5530. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"option1\" id=\"option1_3_";
  5531.                         // line 3885
  5532.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3885$this->source); })()), "html"nulltrue);
  5533.                         echo "\" value=\"";
  5534.                         echo twig_escape_filter($this->env$context["opt1_val"], "html"nulltrue);
  5535.                         echo "\"
  5536. \t\t\t\t\t\t\t               ";
  5537.                         // line 3886
  5538.                         if (((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3886$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "option1", [], "any"truetruefalse3886)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3886$this->source); })()), "option1", [], "any"falsefalsefalse3886) == $context["opt1_val"])) || (twig_length_filter($this->env, (isset($context["p_option1"]) || array_key_exists("p_option1"$context) ? $context["p_option1"] : (function () { throw new RuntimeError('Variable "p_option1" does not exist.'3886$this->source); })())) == 1))) {
  5539.                             echo "checked";
  5540.                         }
  5541.                         echo ">
  5542. \t\t\t\t\t\t\t        ";
  5543.                         // line 3887
  5544.                         echo twig_escape_filter($this->env$context["opt1_val"], "html"nulltrue);
  5545.                         echo "
  5546. \t\t\t\t\t\t\t      </label>
  5547. \t\t\t\t\t\t\t    ";
  5548.                     }
  5549.                 }
  5550.                 $_parent $context['_parent'];
  5551.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['opt1_val'], $context['_parent'], $context['loop']);
  5552.                 $context array_intersect_key($context$_parent) + $_parent;
  5553.                 // line 3890
  5554.                 echo "\t\t\t\t\t\t\t  </div>
  5555. \t\t\t\t\t\t\t</div>
  5556. \t\t\t\t\t\t\t";
  5557.             }
  5558.             // line 3893
  5559.             echo "
  5560. \t\t\t\t\t\t\t";
  5561.             // line 3895
  5562.             echo "\t\t\t\t\t\t\t";
  5563.             if (((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3895$this->source); })()) && twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3895$this->source); })())))) {
  5564.                 // line 3896
  5565.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5566. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">カラー";
  5567.                 // line 3897
  5568.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3897$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3897$this->source); })()), "pc", [], "any"falsefalsefalse3897))) {
  5569.                     echo ": <span>";
  5570.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3897$this->source); })()), "pc", [], "any"falsefalsefalse3897), "html"nulltrue);
  5571.                     echo "</span>";
  5572.                 }
  5573.                 echo "</div>
  5574. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5575. \t\t\t\t\t\t\t    ";
  5576.                 // line 3899
  5577.                 $context["idx"] = 0;
  5578.                 // line 3900
  5579.                 echo "\t\t\t\t\t\t\t    ";
  5580.                 $context['_parent'] = $context;
  5581.                 $context['_seq'] = twig_ensure_traversable((isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3900$this->source); })()));
  5582.                 foreach ($context['_seq'] as $context["_key"] => $context["cc"]) {
  5583.                     if (($context["cc"] && twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3900))) {
  5584.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3900$this->source); })()) + 1);
  5585.                         // line 3901
  5586.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5587.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3901$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3901$this->source); })()), "pc", [], "any"falsefalsefalse3901) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3901))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3901$this->source); })())) == 1))) {
  5588.                             echo " is-selected";
  5589.                         }
  5590.                         echo "\"
  5591. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pc','cc3_";
  5592.                         // line 3902
  5593.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3902$this->source); })()), "html"nulltrue);
  5594.                         echo "');\">
  5595. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"color3\" id=\"cc3_";
  5596.                         // line 3903
  5597.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'3903$this->source); })()), "html"nulltrue);
  5598.                         echo "\" value=\"";
  5599.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3903), "html"nulltrue);
  5600.                         echo "\"
  5601. \t\t\t\t\t\t\t               ";
  5602.                         // line 3904
  5603.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3904$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3904$this->source); })()), "pc", [], "any"falsefalsefalse3904) == twig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3904))) || (twig_length_filter($this->env, (isset($context["color"]) || array_key_exists("color"$context) ? $context["color"] : (function () { throw new RuntimeError('Variable "color" does not exist.'3904$this->source); })())) == 1))) {
  5604.                             echo "checked";
  5605.                         }
  5606.                         echo ">
  5607. \t\t\t\t\t\t\t        ";
  5608.                         // line 3905
  5609.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["cc"], "name", [], "array"falsefalsefalse3905), "html"nulltrue);
  5610.                         echo "
  5611. \t\t\t\t\t\t\t      </label>
  5612. \t\t\t\t\t\t\t    ";
  5613.                     }
  5614.                 }
  5615.                 $_parent $context['_parent'];
  5616.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['cc'], $context['_parent'], $context['loop']);
  5617.                 $context array_intersect_key($context$_parent) + $_parent;
  5618.                 // line 3908
  5619.                 echo "\t\t\t\t\t\t\t  </div>
  5620. \t\t\t\t\t\t\t</div>
  5621. \t\t\t\t\t\t\t";
  5622.             }
  5623.             // line 3911
  5624.             echo "
  5625. \t\t\t\t\t\t\t";
  5626.             // line 3913
  5627.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5628. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">台数</label>
  5629. \t\t\t\t\t\t\t  <div class=\"col-4\">
  5630. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  5631. \t\t\t\t\t\t\t      <input type=\"number\" name=\"daisu\" id=\"daisu\" class=\"form-control\" value=\"";
  5632.             // line 3917
  5633.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "daisu", [], "any"truetruefalse3917)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "daisu", [], "any"falsefalsefalse3917), "1")) : ("1")), "html"nulltrue);
  5634.             echo "\" min=\"1\" max=\"10\" onchange=\"mitsumori_simulation('daisu','daisu');\">
  5635. \t\t\t\t\t\t\t      <span class=\"input-group-text\">台</span>
  5636. \t\t\t\t\t\t\t    </div>
  5637. \t\t\t\t\t\t\t  </div>
  5638. \t\t\t\t\t\t\t  <div class=\"col-4\">
  5639. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"daisu(+1);\">+</button>
  5640. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"daisu(-1);\">ー</button>
  5641. \t\t\t\t\t\t\t  </div>
  5642. \t\t\t\t\t\t\t</div>
  5643. \t\t\t\t\t\t";
  5644.         }
  5645.         // line 3928
  5646.         echo "
  5647. \t\t\t\t\t\t<!-- 4: 施工見積(フェンス・組み立て式) -->
  5648. \t\t\t\t\t\t";
  5649.         // line 3930
  5650.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3930$this->source); })()), "SaleType", [], "any"falsefalsefalse3930), "id", [], "any"falsefalsefalse3930) == 4)) {
  5651.             // line 3931
  5652.             echo "
  5653. \t\t\t\t\t\t\t";
  5654.             // line 3933
  5655.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5656. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">枚数</label>
  5657. \t\t\t\t\t\t\t  <div class=\"col-4 mb-3\">
  5658. \t\t\t\t\t\t\t    <div class=\"input-group\">
  5659. \t\t\t\t\t\t\t      <input type=\"number\" name=\"maisu\" id=\"maisu\" class=\"form-control\" value=\"";
  5660.             // line 3937
  5661.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maisu", [], "any"truetruefalse3937)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "maisu", [], "any"falsefalsefalse3937), "3")) : ("3")), "html"nulltrue);
  5662.             echo "\" min=\"3\" max=\"20\" onchange=\"if(parseInt(this.value)<3)this.value=3; mitsumori_simulation('maisu','maisu');\">
  5663. \t\t\t\t\t\t\t      <span class=\"input-group-text\">枚</span>
  5664. \t\t\t\t\t\t\t    </div>
  5665. \t\t\t\t\t\t\t  </div>
  5666. \t\t\t\t\t\t\t  <div class=\"col-4\">
  5667. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"maisu(+1);\">+</button>
  5668. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"maisu(-1);\">ー</button>
  5669. \t\t\t\t\t\t\t  </div>
  5670. \t\t\t\t\t\t\t</div>
  5671. \t\t\t\t\t\t";
  5672.         }
  5673.         // line 3948
  5674.         echo "
  5675. \t\t\t\t\t\t<!-- 5: 施工見積(ウッドデッキ・タイルデッキ) -->
  5676. \t\t\t\t\t\t";
  5677.         // line 3950
  5678.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'3950$this->source); })()), "SaleType", [], "any"falsefalsefalse3950), "id", [], "any"falsefalsefalse3950) == 5)) {
  5679.             // line 3951
  5680.             echo "
  5681. \t\t\t\t\t\t\t";
  5682.             // line 3953
  5683.             echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5684. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">ステップ</div>
  5685. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5686. \t\t\t\t\t\t\t    ";
  5687.             // line 3956
  5688.             $context["step_yes_checked"] = (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3956$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse3956)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3956$this->source); })()), "deck_step", [], "any"falsefalsefalse3956) == "必要"));
  5689.             // line 3957
  5690.             echo "\t\t\t\t\t\t\t    ";
  5691.             $context["step_no_checked"] = ((( !(isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3957$this->source); })()) ||  !twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_step", [], "any"truetruefalse3957)) || (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3957$this->source); })()), "deck_step", [], "any"falsefalsefalse3957) == "不要")) ||  !twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3957$this->source); })()), "deck_step", [], "any"falsefalsefalse3957));
  5692.             // line 3958
  5693.             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  5694.             if ((isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'3958$this->source); })())) {
  5695.                 echo " is-selected";
  5696.             }
  5697.             echo "\"
  5698. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_yes');\">
  5699. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_yes\" value=\"必要\"
  5700. \t\t\t\t\t\t\t             ";
  5701.             // line 3961
  5702.             if ((isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'3961$this->source); })())) {
  5703.                 echo "checked";
  5704.             }
  5705.             echo ">
  5706. \t\t\t\t\t\t\t      必要
  5707. \t\t\t\t\t\t\t    </label>
  5708. \t\t\t\t\t\t\t    <label class=\"opt-btn";
  5709.             // line 3964
  5710.             if ((isset($context["step_no_checked"]) || array_key_exists("step_no_checked"$context) ? $context["step_no_checked"] : (function () { throw new RuntimeError('Variable "step_no_checked" does not exist.'3964$this->source); })())) {
  5711.                 echo " is-selected";
  5712.             }
  5713.             echo "\"
  5714. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_no');\">
  5715. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_no\" value=\"不要\"
  5716. \t\t\t\t\t\t\t             ";
  5717.             // line 3967
  5718.             if ((isset($context["step_no_checked"]) || array_key_exists("step_no_checked"$context) ? $context["step_no_checked"] : (function () { throw new RuntimeError('Variable "step_no_checked" does not exist.'3967$this->source); })())) {
  5719.                 echo "checked";
  5720.             }
  5721.             echo ">
  5722. \t\t\t\t\t\t\t      不要
  5723. \t\t\t\t\t\t\t    </label>
  5724. \t\t\t\t\t\t\t  </div>
  5725. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-step\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  5726.             // line 3971
  5727.             if ( !(isset($context["step_yes_checked"]) || array_key_exists("step_yes_checked"$context) ? $context["step_yes_checked"] : (function () { throw new RuntimeError('Variable "step_yes_checked" does not exist.'3971$this->source); })())) {
  5728.                 echo "display:none;";
  5729.             }
  5730.             echo "\">
  5731. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  5732. \t\t\t\t\t\t\t  </div>
  5733. \t\t\t\t\t\t\t</div>
  5734. \t\t\t\t\t\t\t";
  5735.             // line 3977
  5736.             echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5737. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">デッキフェンス</div>
  5738. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5739. \t\t\t\t\t\t\t    ";
  5740.             // line 3980
  5741.             $context["fence_yes_checked"] = (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3980$this->source); })()) && twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse3980)) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3980$this->source); })()), "deck_fence", [], "any"falsefalsefalse3980) == "必要"));
  5742.             // line 3981
  5743.             echo "\t\t\t\t\t\t\t    ";
  5744.             $context["fence_no_checked"] = ((( !(isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3981$this->source); })()) ||  !twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "deck_fence", [], "any"truetruefalse3981)) || (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3981$this->source); })()), "deck_fence", [], "any"falsefalsefalse3981) == "不要")) ||  !twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'3981$this->source); })()), "deck_fence", [], "any"falsefalsefalse3981));
  5745.             // line 3982
  5746.             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  5747.             if ((isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'3982$this->source); })())) {
  5748.                 echo " is-selected";
  5749.             }
  5750.             echo "\"
  5751. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_yes');\">
  5752. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_yes\" value=\"必要\"
  5753. \t\t\t\t\t\t\t             ";
  5754.             // line 3985
  5755.             if ((isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'3985$this->source); })())) {
  5756.                 echo "checked";
  5757.             }
  5758.             echo ">
  5759. \t\t\t\t\t\t\t      必要
  5760. \t\t\t\t\t\t\t    </label>
  5761. \t\t\t\t\t\t\t    <label class=\"opt-btn";
  5762.             // line 3988
  5763.             if ((isset($context["fence_no_checked"]) || array_key_exists("fence_no_checked"$context) ? $context["fence_no_checked"] : (function () { throw new RuntimeError('Variable "fence_no_checked" does not exist.'3988$this->source); })())) {
  5764.                 echo " is-selected";
  5765.             }
  5766.             echo "\"
  5767. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_no');\">
  5768. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_no\" value=\"不要\"
  5769. \t\t\t\t\t\t\t             ";
  5770.             // line 3991
  5771.             if ((isset($context["fence_no_checked"]) || array_key_exists("fence_no_checked"$context) ? $context["fence_no_checked"] : (function () { throw new RuntimeError('Variable "fence_no_checked" does not exist.'3991$this->source); })())) {
  5772.                 echo "checked";
  5773.             }
  5774.             echo ">
  5775. \t\t\t\t\t\t\t      不要
  5776. \t\t\t\t\t\t\t    </label>
  5777. \t\t\t\t\t\t\t  </div>
  5778. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-fence\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  5779.             // line 3995
  5780.             if ( !(isset($context["fence_yes_checked"]) || array_key_exists("fence_yes_checked"$context) ? $context["fence_yes_checked"] : (function () { throw new RuntimeError('Variable "fence_yes_checked" does not exist.'3995$this->source); })())) {
  5781.                 echo "display:none;";
  5782.             }
  5783.             echo "\">
  5784. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  5785. \t\t\t\t\t\t\t  </div>
  5786. \t\t\t\t\t\t\t</div>
  5787. \t\t\t\t\t\t";
  5788.         }
  5789.         // line 4001
  5790.         echo "
  5791. \t\t\t\t\t\t<!-- 6: 施工見積(芝生・枚数・数量買い) -->
  5792. \t\t\t\t\t\t";
  5793.         // line 4003
  5794.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4003$this->source); })()), "SaleType", [], "any"falsefalsefalse4003), "id", [], "any"falsefalsefalse4003) == 6)) {
  5795.             // line 4004
  5796.             echo "
  5797. \t\t\t\t\t\t\t";
  5798.             // line 4006
  5799.             echo "\t\t\t\t\t\t\t";
  5800.             if ((((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4006$this->source); })()) && twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4006$this->source); })()))) && (twig_join_filter((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4006$this->source); })())) != ""))) {
  5801.                 // line 4007
  5802.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5803. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">規格";
  5804.                 // line 4008
  5805.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4008$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4008$this->source); })()), "pm", [], "any"falsefalsefalse4008))) {
  5806.                     echo ": <span>";
  5807.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4008$this->source); })()), "pm", [], "any"falsefalsefalse4008), "html"nulltrue);
  5808.                     echo "</span>";
  5809.                 }
  5810.                 echo "</div>
  5811. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5812. \t\t\t\t\t\t\t    ";
  5813.                 // line 4010
  5814.                 $context["idx"] = 0;
  5815.                 // line 4011
  5816.                 echo "\t\t\t\t\t\t\t    ";
  5817.                 $context['_parent'] = $context;
  5818.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4011$this->source); })()));
  5819.                 foreach ($context['_seq'] as $context["_key"] => $context["pm_val"]) {
  5820.                     if ($context["pm_val"]) {
  5821.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4011$this->source); })()) + 1);
  5822.                         // line 4012
  5823.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5824.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4012$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4012$this->source); })()), "pm", [], "any"falsefalsefalse4012) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4012$this->source); })())) == 1))) {
  5825.                             echo " is-selected";
  5826.                         }
  5827.                         echo "\"
  5828. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm6_";
  5829.                         // line 4013
  5830.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4013$this->source); })()), "html"nulltrue);
  5831.                         echo "');\">
  5832. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm6_";
  5833.                         // line 4014
  5834.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4014$this->source); })()), "html"nulltrue);
  5835.                         echo "\" value=\"";
  5836.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  5837.                         echo "\"
  5838. \t\t\t\t\t\t\t               ";
  5839.                         // line 4015
  5840.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4015$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4015$this->source); })()), "pm", [], "any"falsefalsefalse4015) == $context["pm_val"])) || (twig_length_filter($this->env, (isset($context["p_m"]) || array_key_exists("p_m"$context) ? $context["p_m"] : (function () { throw new RuntimeError('Variable "p_m" does not exist.'4015$this->source); })())) == 1))) {
  5841.                             echo "checked";
  5842.                         }
  5843.                         echo ">
  5844. \t\t\t\t\t\t\t        ";
  5845.                         // line 4016
  5846.                         echo twig_escape_filter($this->env$context["pm_val"], "html"nulltrue);
  5847.                         echo "
  5848. \t\t\t\t\t\t\t      </label>
  5849. \t\t\t\t\t\t\t    ";
  5850.                     }
  5851.                 }
  5852.                 $_parent $context['_parent'];
  5853.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pm_val'], $context['_parent'], $context['loop']);
  5854.                 $context array_intersect_key($context$_parent) + $_parent;
  5855.                 // line 4019
  5856.                 echo "\t\t\t\t\t\t\t  </div>
  5857. \t\t\t\t\t\t\t</div>
  5858. \t\t\t\t\t\t\t";
  5859.             }
  5860.             // line 4022
  5861.             echo "
  5862. \t\t\t\t\t\t\t";
  5863.             // line 4025
  5864.             echo "\t\t\t\t\t\t\t";
  5865.             if ((((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4025$this->source); })()) && twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4025$this->source); })()))) && (twig_join_filter((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4025$this->source); })())) != ""))) {
  5866.                 // line 4026
  5867.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5868. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">芝の幅";
  5869.                 // line 4027
  5870.                 if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4027$this->source); })()) && twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4027$this->source); })()), "pw", [], "any"falsefalsefalse4027))) {
  5871.                     echo ": <span>";
  5872.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4027$this->source); })()), "pw", [], "any"falsefalsefalse4027), "html"nulltrue);
  5873.                     echo "</span>";
  5874.                 }
  5875.                 echo "</div>
  5876. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  5877. \t\t\t\t\t\t\t    ";
  5878.                 // line 4029
  5879.                 $context["idx"] = 0;
  5880.                 // line 4030
  5881.                 echo "\t\t\t\t\t\t\t    ";
  5882.                 $context['_parent'] = $context;
  5883.                 $context['_seq'] = twig_ensure_traversable((isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4030$this->source); })()));
  5884.                 foreach ($context['_seq'] as $context["_key"] => $context["pw_val"]) {
  5885.                     if ($context["pw_val"]) {
  5886.                         $context["idx"] = ((isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4030$this->source); })()) + 1);
  5887.                         // line 4031
  5888.                         echo "\t\t\t\t\t\t\t      <label class=\"opt-btn";
  5889.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4031$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4031$this->source); })()), "pw", [], "any"falsefalsefalse4031) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4031$this->source); })())) == 1))) {
  5890.                             echo " is-selected";
  5891.                         }
  5892.                         echo "\"
  5893. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw6_";
  5894.                         // line 4032
  5895.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4032$this->source); })()), "html"nulltrue);
  5896.                         echo "');\">
  5897. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw6_";
  5898.                         // line 4033
  5899.                         echo twig_escape_filter($this->env, (isset($context["idx"]) || array_key_exists("idx"$context) ? $context["idx"] : (function () { throw new RuntimeError('Variable "idx" does not exist.'4033$this->source); })()), "html"nulltrue);
  5900.                         echo "\" value=\"";
  5901.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5902.                         echo "\"
  5903. \t\t\t\t\t\t\t               ";
  5904.                         // line 4034
  5905.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4034$this->source); })()) && (twig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4034$this->source); })()), "pw", [], "any"falsefalsefalse4034) == $context["pw_val"])) || (twig_length_filter($this->env, (isset($context["p_w"]) || array_key_exists("p_w"$context) ? $context["p_w"] : (function () { throw new RuntimeError('Variable "p_w" does not exist.'4034$this->source); })())) == 1))) {
  5906.                             echo "checked";
  5907.                         }
  5908.                         echo ">
  5909. \t\t\t\t\t\t\t        ";
  5910.                         // line 4035
  5911.                         echo twig_escape_filter($this->env$context["pw_val"], "html"nulltrue);
  5912.                         echo "
  5913. \t\t\t\t\t\t\t      </label>
  5914. \t\t\t\t\t\t\t    ";
  5915.                     }
  5916.                 }
  5917.                 $_parent $context['_parent'];
  5918.                 unset($context['_seq'], $context['_iterated'], $context['_key'], $context['pw_val'], $context['_parent'], $context['loop']);
  5919.                 $context array_intersect_key($context$_parent) + $_parent;
  5920.                 // line 4038
  5921.                 echo "\t\t\t\t\t\t\t  </div>
  5922. \t\t\t\t\t\t\t</div>
  5923. \t\t\t\t\t\t\t";
  5924.             }
  5925.             // line 4041
  5926.             echo "
  5927. \t\t\t\t\t\t\t";
  5928.             // line 4043
  5929.             echo "\t\t\t\t\t\t\t";
  5930.             $context["_roll_h"] = (((array_key_exists("p_h"$context) && twig_length_filter($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4043$this->source); })())))) ? (twig_first($this->env, (isset($context["p_h"]) || array_key_exists("p_h"$context) ? $context["p_h"] : (function () { throw new RuntimeError('Variable "p_h" does not exist.'4043$this->source); })()))) : (""));
  5931.             // line 4044
  5932.             echo "\t\t\t\t\t\t\t";
  5933.             if ((isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4044$this->source); })())) {
  5934.                 // line 4045
  5935.                 echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5936. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">1ロールの長さ:<span style=\"font-weight:bold;\">";
  5937.                 // line 4046
  5938.                 if (twig_in_filter("cm", (isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4046$this->source); })()))) {
  5939.                     echo twig_escape_filter($this->env, (twig_trim_filter(twig_replace_filter((isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4046$this->source); })()), ["cm" => """," => ""])) / 100), "html"nulltrue);
  5940.                     echo "m";
  5941.                 } else {
  5942.                     echo twig_escape_filter($this->env, (isset($context["_roll_h"]) || array_key_exists("_roll_h"$context) ? $context["_roll_h"] : (function () { throw new RuntimeError('Variable "_roll_h" does not exist.'4046$this->source); })()), "html"nulltrue);
  5943.                 }
  5944.                 echo "</span></div>
  5945. \t\t\t\t\t\t\t</div>
  5946. \t\t\t\t\t\t\t";
  5947.             }
  5948.             // line 4049
  5949.             echo "
  5950. \t\t\t\t\t\t\t";
  5951.             // line 4052
  5952.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  5953. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">施工サイズ</label>
  5954. \t\t\t\t\t\t\t  <div class=\"col-8\">
  5955. \t\t\t\t\t\t\t    <div class=\"input-group\">
  5956. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_len\" id=\"tf_len\"
  5957. \t\t\t\t\t\t\t        class=\"form-control\"
  5958. \t\t\t\t\t\t\t        value=\"";
  5959.             // line 4058
  5960.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_len", [], "any"truetruefalse4058)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_len", [], "any"falsefalsefalse4058), "")) : ("")), "html"nulltrue);
  5961.             echo "\"
  5962. \t\t\t\t\t\t\t        placeholder=\"縦\" min=\"0.1\" step=\"0.1\"
  5963. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_len','tf_len');\">
  5964. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m&nbsp;×</span>
  5965. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_wid\" id=\"tf_wid\"
  5966. \t\t\t\t\t\t\t        class=\"form-control\"
  5967. \t\t\t\t\t\t\t        value=\"";
  5968.             // line 4064
  5969.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_wid", [], "any"truetruefalse4064)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_wid", [], "any"falsefalsefalse4064), "")) : ("")), "html"nulltrue);
  5970.             echo "\"
  5971. \t\t\t\t\t\t\t        placeholder=\"横\" min=\"0.1\" step=\"0.1\"
  5972. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_wid','tf_wid');\">
  5973. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m</span>
  5974. \t\t\t\t\t\t\t    </div>
  5975. \t\t\t\t\t\t\t    ";
  5976.             // line 4070
  5977.             echo "\t\t\t\t\t\t\t    <input type=\"hidden\" name=\"area\" id=\"area\" value=\"";
  5978.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "area", [], "any"truetruefalse4070)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "area", [], "any"falsefalsefalse4070), "")) : ("")), "html"nulltrue);
  5979.             echo "\">
  5980. \t\t\t\t\t\t\t    ";
  5981.             // line 4073
  5982.             echo "\t\t\t\t\t\t\t    <div style=\"margin-top:10px;display:inline-block;background:#fff3cd;border:1px solid #ffe69c;border-radius:6px;padding:8px 14px;font-size:16px;color:#c00;font-weight:bold;\">
  5983. \t\t\t\t\t\t\t      必要枚数:<input type=\"number\" name=\"tf_qty\" id=\"tf_qty\"
  5984. \t\t\t\t\t\t\t        value=\"";
  5985.             // line 4075
  5986.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_qty", [], "any"truetruefalse4075)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "tf_qty", [], "any"falsefalsefalse4075), "1")) : ("1")), "html"nulltrue);
  5987.             echo "\" min=\"1\" step=\"1\"
  5988. \t\t\t\t\t\t\t        style=\"width:80px;font-size:22px;font-weight:bold;color:#c00;text-align:right;border:1px solid #ffe69c;border-radius:4px;padding:2px 6px;\"
  5989. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_qty','tf_qty');\"> 枚
  5990. \t\t\t\t\t\t\t    </div>
  5991. \t\t\t\t\t\t\t    <div style=\"margin-top:6px;font-size:12px;color:#666;\">※ 施工サイズを入力すると必要枚数を自動計算します。サイズが分からない場合は枚数を直接ご指定ください。</div>
  5992. \t\t\t\t\t\t\t  </div>
  5993. \t\t\t\t\t\t\t</div>
  5994. \t\t\t\t\t\t";
  5995.         }
  5996.         // line 4084
  5997.         echo "
  5998. \t\t\t\t\t\t<!-- 7: 施工見積(数量買い・基本工事費固定) -->
  5999. \t\t\t\t\t\t";
  6000.         // line 4086
  6001.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4086$this->source); })()), "SaleType", [], "any"falsefalsefalse4086), "id", [], "any"falsefalsefalse4086) == 7)) {
  6002.             // line 4087
  6003.             echo "\t\t\t\t\t\t\t";
  6004.             // line 4088
  6005.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6006. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">個数</label>
  6007. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6008. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  6009. \t\t\t\t\t\t\t      <input type=\"number\" name=\"suuryou\" id=\"suuryou\" class=\"form-control\"
  6010. \t\t\t\t\t\t\t        value=\"";
  6011.             // line 4093
  6012.             echo twig_escape_filter($this->env, ((twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "suuryou", [], "any"truetruefalse4093)) ? (_twig_default_filter(twig_get_attribute($this->env$this->source, ($context["mitsumori_json"] ?? null), "suuryou", [], "any"falsefalsefalse4093), "1")) : ("1")), "html"nulltrue);
  6013.             echo "\" min=\"1\" max=\"100\"
  6014. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('suuryou','suuryou');\">
  6015. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  6016. \t\t\t\t\t\t\t    </div>
  6017. \t\t\t\t\t\t\t  </div>
  6018. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6019. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"suuryou(+1);\">+</button>
  6020. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"suuryou(-1);\">ー</button>
  6021. \t\t\t\t\t\t\t  </div>
  6022. \t\t\t\t\t\t\t</div>
  6023. \t\t\t\t\t\t";
  6024.         }
  6025.         // line 4104
  6026.         echo "
  6027. \t\t\t\t\t\t<!-- 9: 商品のみ購入 -->
  6028. \t\t\t\t\t\t";
  6029.         // line 4106
  6030.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4106$this->source); })()), "SaleType", [], "any"falsefalsefalse4106), "id", [], "any"falsefalsefalse4106) == 9)) {
  6031.             // line 4107
  6032.             echo "\t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6033. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">数量</label>
  6034. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6035. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  6036. \t\t\t\t\t\t\t      <input type=\"number\" name=\"quantity_only\" id=\"quantity_only\" class=\"form-control\" value=\"1\" min=\"1\" onchange=\"\$('#quantity').val(this.value);\">
  6037. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  6038. \t\t\t\t\t\t\t    </div>
  6039. \t\t\t\t\t\t\t  </div>
  6040. \t\t\t\t\t\t\t  <div class=\"col-4\">
  6041. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"quantityOnly(+1);\">+</button>
  6042. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"quantityOnly(-1);\">ー</button>
  6043. \t\t\t\t\t\t\t  </div>
  6044. \t\t\t\t\t\t\t</div>
  6045. \t\t\t\t\t\t";
  6046.         }
  6047.         // line 4121
  6048.         echo "
  6049. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">取り付け工事のご希望に関してお答えください。</label></div>
  6050. \t\t\t\t\t\t";
  6051.         // line 4129
  6052.         echo "\t\t\t\t\t\t";
  6053.         $context["is_gs"] = false;
  6054.         // line 4130
  6055.         echo "\t\t\t\t\t\t";
  6056.         $context["is_cg"] = false;
  6057.         // line 4131
  6058.         echo "\t\t\t\t\t\t";
  6059.         if ( !twig_test_empty(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4131$this->source); })()), "ProductCategories", [], "any"falsefalsefalse4131))) {
  6060.             // line 4132
  6061.             echo "\t\t\t\t\t\t\t";
  6062.             $context['_parent'] = $context;
  6063.             $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4132$this->source); })()), "ProductCategories", [], "any"falsefalsefalse4132));
  6064.             foreach ($context['_seq'] as $context["_key"] => $context["ProductCategory"]) {
  6065.                 // line 4133
  6066.                 echo "\t\t\t\t\t\t\t\t";
  6067.                 if ((twig_get_attribute($this->env$this->source$context["ProductCategory"], "category_id", [], "any"falsefalsefalse4133) == 27)) {
  6068.                     $context["is_gs"] = true;
  6069.                 }
  6070.                 // line 4134
  6071.                 echo "\t\t\t\t\t\t\t\t";
  6072.                 if ((twig_get_attribute($this->env$this->source$context["ProductCategory"], "category_id", [], "any"falsefalsefalse4134) == 9)) {
  6073.                     $context["is_cg"] = true;
  6074.                 }
  6075.                 // line 4135
  6076.                 echo "\t\t\t\t\t\t\t";
  6077.             }
  6078.             $_parent $context['_parent'];
  6079.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ProductCategory'], $context['_parent'], $context['loop']);
  6080.             $context array_intersect_key($context$_parent) + $_parent;
  6081.             // line 4136
  6082.             echo "\t\t\t\t\t\t";
  6083.         }
  6084.         // line 4137
  6085.         echo "\t\t\t\t\t\t";
  6086.         $context['_parent'] = $context;
  6087.         $context['_seq'] = twig_ensure_traversable(range(010));
  6088.         foreach ($context['_seq'] as $context["_key"] => $context["i"]) {
  6089.             // line 4138
  6090.             echo "\t\t\t\t\t\t\t";
  6091.             if (((isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4138$this->source); })()) && (twig_length_filter($this->env, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4138$this->source); })())) >= ($context["i"] + 1)))) {
  6092.                 // line 4139
  6093.                 echo "\t\t\t\t\t\t\t";
  6094.                 if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4139$this->source); })()), $context["i"], [], "array"falsefalsefalse4139), "name", [], "array"falsefalsefalse4139)) {
  6095.                     // line 4140
  6096.                     echo "\t\t\t\t\t\t\t";
  6097.                     $context["hide_opt"] = false;
  6098.                     // line 4141
  6099.                     echo "\t\t\t\t\t\t\t";
  6100.                     if (((isset($context["is_gs"]) || array_key_exists("is_gs"$context) ? $context["is_gs"] : (function () { throw new RuntimeError('Variable "is_gs" does not exist.'4141$this->source); })()) && (preg_match("/撤去/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4141$this->source); })()), $context["i"], [], "array"falsefalsefalse4141), "name", [], "array"falsefalsefalse4141)) || preg_match("/残土/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4141$this->source); })()), $context["i"], [], "array"falsefalsefalse4141), "name", [], "array"falsefalsefalse4141))))) {
  6101.                         // line 4142
  6102.                         echo "\t\t\t\t\t\t\t\t";
  6103.                         $context["hide_opt"] = true;
  6104.                         // line 4143
  6105.                         echo "\t\t\t\t\t\t\t";
  6106.                     }
  6107.                     // line 4144
  6108.                     echo "\t\t\t\t\t\t\t";
  6109.                     if (((isset($context["is_cg"]) || array_key_exists("is_cg"$context) ? $context["is_cg"] : (function () { throw new RuntimeError('Variable "is_cg" does not exist.'4144$this->source); })()) && preg_match("/残土/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4144$this->source); })()), $context["i"], [], "array"falsefalsefalse4144), "name", [], "array"falsefalsefalse4144)))) {
  6110.                         // line 4145
  6111.                         echo "\t\t\t\t\t\t\t\t";
  6112.                         $context["hide_opt"] = true;
  6113.                         // line 4146
  6114.                         echo "\t\t\t\t\t\t\t";
  6115.                     }
  6116.                     // line 4147
  6117.                     echo "\t\t\t\t\t\t\t";
  6118.                     if ( !(isset($context["hide_opt"]) || array_key_exists("hide_opt"$context) ? $context["hide_opt"] : (function () { throw new RuntimeError('Variable "hide_opt" does not exist.'4147$this->source); })())) {
  6119.                         // line 4148
  6120.                         echo "\t\t\t\t\t\t\t";
  6121.                         // line 4150
  6122.                         echo "\t\t\t\t\t\t\t";
  6123.                         $context["is_removal_unknown"] = (((((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4150), "price", [], "array"truetruefalse4150)) ? (_twig_default_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4150), "price", [], "array"falsefalsefalse4150), 0)) : (0)) == 0) || (((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4150), "price", [], "array"truetruefalse4150)) ? (_twig_default_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, ($context["op"] ?? null), $context["i"], [], "array"falsetruefalse4150), "price", [], "array"falsefalsefalse4150), "0")) : ("0")) == "0")) && ((preg_match("/解体/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source,                         // line 4151
  6124. (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4151$this->source); })()), $context["i"], [], "array"falsefalsefalse4151), "name", [], "array"falsefalsefalse4151)) || preg_match("/撤去/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4151$this->source); })()), $context["i"], [], "array"falsefalsefalse4151), "name", [], "array"falsefalsefalse4151))) || preg_match("/設置場所/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4151$this->source); })()), $context["i"], [], "array"falsefalsefalse4151), "name", [], "array"falsefalsefalse4151))));
  6125.                         // line 4152
  6126.                         echo "\t\t\t\t\t\t\t";
  6127.                         // line 4153
  6128.                         echo "\t\t\t\t\t\t\t";
  6129.                         $context["is_tf_kouji"] = ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4153$this->source); })()), "SaleType", [], "any"falsefalsefalse4153), "id", [], "any"falsefalsefalse4153) == 6) && preg_match("/取り付け工事/"twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4153$this->source); })()), $context["i"], [], "array"falsefalsefalse4153), "name", [], "array"falsefalsefalse4153)));
  6130.                         // line 4154
  6131.                         echo "\t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" data-op-idx=\"";
  6132.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6133.                         echo "\" data-op-name=\"";
  6134.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4154$this->source); })()), $context["i"], [], "array"falsefalsefalse4154), "name", [], "array"falsefalsefalse4154), "html_attr");
  6135.                         echo "\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  6136. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">";
  6137.                         // line 4156
  6138.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4156$this->source); })()), $context["i"], [], "array"falsefalsefalse4156), "name", [], "array"falsefalsefalse4156), "html"nulltrue);
  6139.                         if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4156$this->source); })()) && twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4156$this->source); })()), "op", [], "any"falsefalsefalse4156), $context["i"], [], "array"falsefalsefalse4156))) {
  6140.                             echo ": <span>";
  6141.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4156$this->source); })()), "op", [], "any"falsefalsefalse4156), $context["i"], [], "array"falsefalsefalse4156), "html"nulltrue);
  6142.                             echo "</span>";
  6143.                         }
  6144.                         echo "</div>
  6145. \t\t\t\t\t\t\t  ";
  6146.                         // line 4157
  6147.                         if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4157$this->source); })()), $context["i"], [], "array"falsefalsefalse4157), "comment", [], "array"falsefalsefalse4157)) {
  6148.                             echo "<div class=\"opt-comment\" style=\"font-size:12px;color:#666;margin:4px 0 6px;\">";
  6149.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4157$this->source); })()), $context["i"], [], "array"falsefalsefalse4157), "comment", [], "array"falsefalsefalse4157), "html"nulltrue);
  6150.                             echo "</div>";
  6151.                         }
  6152.                         // line 4158
  6153.                         echo "\t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  6154. \t\t\t\t\t\t\t    ";
  6155.                         // line 4161
  6156.                         echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6157.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4161$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4161$this->source); })()), "op", [], "any"falsefalsefalse4161), $context["i"], [], "array"falsefalsefalse4161) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4161$this->source); })()), $context["i"], [], "array"falsefalsefalse4161), "on", [], "array"falsefalsefalse4161))) ||  !twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4161$this->source); })()), $context["i"], [], "array"falsefalsefalse4161), "off", [], "array"falsefalsefalse4161))) {
  6158.                             echo " is-selected";
  6159.                         }
  6160.                         echo "\"
  6161. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op";
  6162.                         // line 4162
  6163.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6164.                         echo "','op";
  6165.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6166.                         echo "_1');\">
  6167. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op";
  6168.                         // line 4163
  6169.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6170.                         echo "\" id=\"op";
  6171.                         echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6172.                         echo "_1\" value=\"";
  6173.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4163$this->source); })()), $context["i"], [], "array"falsefalsefalse4163), "on", [], "array"falsefalsefalse4163), "html"nulltrue);
  6174.                         echo "\" ";
  6175.                         if ((((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4163$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4163$this->source); })()), "op", [], "any"falsefalsefalse4163), $context["i"], [], "array"falsefalsefalse4163) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4163$this->source); })()), $context["i"], [], "array"falsefalsefalse4163), "on", [], "array"falsefalsefalse4163))) ||  !twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4163$this->source); })()), $context["i"], [], "array"falsefalsefalse4163), "off", [], "array"falsefalsefalse4163))) {
  6176.                             echo "checked";
  6177.                         }
  6178.                         echo ">
  6179. \t\t\t\t\t\t\t      ";
  6180.                         // line 4164
  6181.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4164$this->source); })()), $context["i"], [], "array"falsefalsefalse4164), "on", [], "array"falsefalsefalse4164), "html"nulltrue);
  6182.                         echo "
  6183. \t\t\t\t\t\t\t    </label>
  6184. \t\t\t\t\t\t\t    ";
  6185.                         // line 4166
  6186.                         if (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4166$this->source); })()), $context["i"], [], "array"falsefalsefalse4166), "off", [], "array"falsefalsefalse4166)) {
  6187.                             // line 4167
  6188.                             echo "\t\t\t\t\t\t\t    <label class=\"opt-btn";
  6189.                             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4167$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4167$this->source); })()), "op", [], "any"falsefalsefalse4167), $context["i"], [], "array"falsefalsefalse4167) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4167$this->source); })()), $context["i"], [], "array"falsefalsefalse4167), "off", [], "array"falsefalsefalse4167)))) {
  6190.                                 echo " is-selected";
  6191.                             }
  6192.                             echo "\"
  6193. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op";
  6194.                             // line 4168
  6195.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6196.                             echo "','op";
  6197.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6198.                             echo "_2');\">
  6199. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op";
  6200.                             // line 4169
  6201.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6202.                             echo "\" id=\"op";
  6203.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6204.                             echo "_2\" value=\"";
  6205.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4169$this->source); })()), $context["i"], [], "array"falsefalsefalse4169), "off", [], "array"falsefalsefalse4169), "html"nulltrue);
  6206.                             echo "\" ";
  6207.                             if (((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4169$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4169$this->source); })()), "op", [], "any"falsefalsefalse4169), $context["i"], [], "array"falsefalsefalse4169) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4169$this->source); })()), $context["i"], [], "array"falsefalsefalse4169), "off", [], "array"falsefalsefalse4169)))) {
  6208.                                 echo "checked";
  6209.                             }
  6210.                             echo ">
  6211. \t\t\t\t\t\t\t      ";
  6212.                             // line 4170
  6213.                             echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4170$this->source); })()), $context["i"], [], "array"falsefalsefalse4170), "off", [], "array"falsefalsefalse4170), "html"nulltrue);
  6214.                             echo "
  6215. \t\t\t\t\t\t\t    </label>
  6216. \t\t\t\t\t\t\t    ";
  6217.                         }
  6218.                         // line 4173
  6219.                         echo "\t\t\t\t\t\t\t  </div>
  6220. \t\t\t\t\t\t\t  ";
  6221.                         // line 4174
  6222.                         if (((isset($context["is_removal_unknown"]) || array_key_exists("is_removal_unknown"$context) ? $context["is_removal_unknown"] : (function () { throw new RuntimeError('Variable "is_removal_unknown" does not exist.'4174$this->source); })()) || (isset($context["is_tf_kouji"]) || array_key_exists("is_tf_kouji"$context) ? $context["is_tf_kouji"] : (function () { throw new RuntimeError('Variable "is_tf_kouji" does not exist.'4174$this->source); })()))) {
  6223.                             // line 4175
  6224.                             echo "\t\t\t\t\t\t\t  <div class=\"opt-survey-note\" data-op-idx=\"";
  6225.                             echo twig_escape_filter($this->env$context["i"], "html"nulltrue);
  6226.                             echo "\" style=\"font-size:12px;color:#c00;margin-top:6px;";
  6227.                             if ( !((isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4175$this->source); })()) && (twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["mitsumori_json"]) || array_key_exists("mitsumori_json"$context) ? $context["mitsumori_json"] : (function () { throw new RuntimeError('Variable "mitsumori_json" does not exist.'4175$this->source); })()), "op", [], "any"falsefalsefalse4175), $context["i"], [], "array"falsefalsefalse4175) == twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["op"]) || array_key_exists("op"$context) ? $context["op"] : (function () { throw new RuntimeError('Variable "op" does not exist.'4175$this->source); })()), $context["i"], [], "array"falsefalsefalse4175), "on", [], "array"falsefalsefalse4175)))) {
  6228.                                 echo "display:none;";
  6229.                             }
  6230.                             echo "\">
  6231. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  6232. \t\t\t\t\t\t\t  </div>
  6233. \t\t\t\t\t\t\t  ";
  6234.                         }
  6235.                         // line 4179
  6236.                         echo "\t\t\t\t\t\t\t</div>
  6237. \t\t\t\t\t\t\t";
  6238.                     }
  6239.                     // line 4181
  6240.                     echo "\t\t\t\t\t\t\t";
  6241.                 }
  6242.                 // line 4182
  6243.                 echo "\t\t\t\t\t\t\t";
  6244.             }
  6245.             // line 4183
  6246.             echo "\t\t\t\t\t\t";
  6247.         }
  6248.         $_parent $context['_parent'];
  6249.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['i'], $context['_parent'], $context['loop']);
  6250.         $context array_intersect_key($context$_parent) + $_parent;
  6251.         // line 4184
  6252.         echo "
  6253. \t\t\t\t\t\t";
  6254.         // line 4188
  6255.         echo "\t\t\t\t\t\t";
  6256.         if ((((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4188$this->source); })()), "SaleType", [], "any"falsefalsefalse4188), "id", [], "any"falsefalsefalse4188) == 4) && (isset($context["oi"]) || array_key_exists("oi"$context) ? $context["oi"] : (function () { throw new RuntimeError('Variable "oi" does not exist.'4188$this->source); })())) && twig_get_attribute($this->env$this->source, (isset($context["oi"]) || array_key_exists("oi"$context) ? $context["oi"] : (function () { throw new RuntimeError('Variable "oi" does not exist.'4188$this->source); })()), "fe_block", [], "any"falsefalsefalse4188))) {
  6257.             // line 4189
  6258.             echo "\t\t\t\t\t\t<div id=\"fe-block-options\" class=\"form-group mt-3 pb-3\" style=\"display:none;border-bottom:1px solid rgba(0,0,0,.125)\"></div>
  6259. \t\t\t\t\t\t";
  6260.         }
  6261.         // line 4191
  6262.         echo "
  6263. \t\t\t\t\t  </div>
  6264. \t\t\t\t\t  <!-- /.card-body -->
  6265. \t\t\t\t\t</div>
  6266.                     <form action=\"";
  6267.         // line 4197
  6268.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_add_cart", ["id" => twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4197$this->source); })()), "id", [], "any"falsefalsefalse4197)]), "html"nulltrue);
  6269.         echo "\" method=\"post\" id=\"form1\" name=\"form1\">
  6270.                         ";
  6271.         // line 4198
  6272.         if (twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4198$this->source); })()), "stock_find", [], "any"falsefalsefalse4198)) {
  6273.             // line 4199
  6274.             echo "                            <div class=\"ec-productRole__actions\">
  6275.                                 ";
  6276.             // line 4200
  6277.             if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id1", [], "any"truetruefalse4200)) {
  6278.                 // line 4201
  6279.                 echo "                                    <div class=\"ec-select\">
  6280.                                         ";
  6281.                 // line 4202
  6282.                 echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4202$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse4202), 'row');
  6283.                 echo "
  6284.                                         ";
  6285.                 // line 4203
  6286.                 echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4203$this->source); })()), "classcategory_id1", [], "any"falsefalsefalse4203), 'errors');
  6287.                 echo "
  6288.                                     </div>
  6289.                                     ";
  6290.                 // line 4205
  6291.                 if (twig_get_attribute($this->env$this->source, ($context["form"] ?? null), "classcategory_id2", [], "any"truetruefalse4205)) {
  6292.                     // line 4206
  6293.                     echo "                                        <div class=\"ec-select\">
  6294.                                             ";
  6295.                     // line 4207
  6296.                     echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4207$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse4207), 'row');
  6297.                     echo "
  6298.                                             ";
  6299.                     // line 4208
  6300.                     echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4208$this->source); })()), "classcategory_id2", [], "any"falsefalsefalse4208), 'errors');
  6301.                     echo "
  6302.                                         </div>
  6303.                                     ";
  6304.                 }
  6305.                 // line 4211
  6306.                 echo "                                ";
  6307.             }
  6308.             // line 4212
  6309.             echo "                                <div class=\"ec-numberInput\">
  6310.                                     ";
  6311.             // line 4213
  6312.             echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4213$this->source); })()), "quantity", [], "any"falsefalsefalse4213), 'widget', ["type" => "hidden"]);
  6313.             echo "
  6314.                                     ";
  6315.             // line 4214
  6316.             echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock(twig_get_attribute($this->env$this->source, (isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4214$this->source); })()), "quantity", [], "any"falsefalsefalse4214), 'errors');
  6317.             echo "
  6318.                                 </div>
  6319.                             </div>
  6320.                         ";
  6321.         } else {
  6322.             // line 4219
  6323.             echo "                            <div class=\"ec-productRole__btn\">
  6324.                                 <button type=\"button\" class=\"ec-blockBtn--action\" disabled=\"disabled\">
  6325.                                     ";
  6326.             // line 4221
  6327.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("ただいま品切れ中です。"), "html"nulltrue);
  6328.             echo "
  6329.                                 </button>
  6330.                             </div>
  6331.                         ";
  6332.         }
  6333.         // line 4225
  6334.         echo "                        <div class=\"ec-productRole__btn mt-3\">
  6335.                            <button type=\"submit\" id=\"cart_btn\" class=\"ec-blockBtn--action add-cart\">カートに入れる</button>
  6336.                         </div>
  6337.                         ";
  6338.         // line 4228
  6339.         echo $this->env->getRuntime('Symfony\Component\Form\FormRenderer')->searchAndRenderBlock((isset($context["form"]) || array_key_exists("form"$context) ? $context["form"] : (function () { throw new RuntimeError('Variable "form" does not exist.'4228$this->source); })()), 'rest');
  6340.         echo "
  6341.                     </form>
  6342.                     <div class=\"ec-modal add-cart-modal\">
  6343.                         <div class=\"ec-modal-overlay\">
  6344.                             <div class=\"ec-modal-wrap add-cart-modal__wrap\">
  6345.                                 <span class=\"ec-modal-close\"><span class=\"ec-icon\"><img src=\"";
  6346.         // line 4233
  6347.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("assets/icon/cross-dark.svg"), "html"nulltrue);
  6348.         echo "\" alt=\"\"/></span></span>
  6349.                                 <div id=\"ec-modal-header\" class=\"text-center add-cart-modal__header\">";
  6350.         // line 4234
  6351.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートに追加しました。"), "html"nulltrue);
  6352.         echo "</div>
  6353.                                 <div class=\"ec-modal-box add-cart-modal__box\">
  6354.                                     <div class=\"ec-role add-cart-modal__actions\">
  6355.                                         <a href=\"";
  6356.         // line 4237
  6357.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("cart");
  6358.         echo "\" class=\"ec-inlineBtn--action add-cart-modal__primary\">";
  6359.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("カートに進む"), "html"nulltrue);
  6360.         echo "</a>
  6361.                                         <span class=\"ec-inlineBtn--cancel add-cart-modal__secondary\">";
  6362.         // line 4238
  6363.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("商品検索を続ける"), "html"nulltrue);
  6364.         echo "</span>
  6365.                                     </div>
  6366.                                 </div>
  6367.                             </div>
  6368.                         </div>
  6369.                     </div>
  6370.                     <div class=\"ec-productRole__description\">";
  6371.         // line 4244
  6372.         echo twig_nl2br(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4244$this->source); })()), "description_detail", [], "any"falsefalsefalse4244));
  6373.         echo "
  6374.                     </div>
  6375.                     ";
  6376.         // line 4248
  6377.         echo "                    <div class=\"ec-productRole__share\">
  6378.                         <ul class=\"ec-share\">
  6379.                             <li class=\"ec-share__item\">
  6380.                                 <a href=\"https://twitter.com/share?url=";
  6381.         // line 4251
  6382.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4251$this->source); })()), "request", [], "any"falsefalsefalse4251), "uri", [], "any"falsefalsefalse4251)), "html"nulltrue);
  6383.         echo "&text=";
  6384.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4251$this->source); })()), "name", [], "any"falsefalsefalse4251)), "html"nulltrue);
  6385.         echo "\" class=\"ec-share__link ec-share__link--twitter\" target=\"_blank\" rel=\"noreferrer noopener\">
  6386.                                     <i class=\"fab fa-twitter\"></i>
  6387.                                 </a>
  6388.                             </li>
  6389.                             <li class=\"ec-share__item\">
  6390.                                 <a href=\"https://www.facebook.com/sharer/sharer.php?u=";
  6391.         // line 4256
  6392.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4256$this->source); })()), "request", [], "any"falsefalsefalse4256), "uri", [], "any"falsefalsefalse4256)), "html"nulltrue);
  6393.         echo "\" class=\"ec-share__link ec-share__link--facebook\" target=\"_blank\" rel=\"noreferrer noopener\">
  6394.                                     <i class=\"fab fa-facebook-f\"></i>
  6395.                                 </a>
  6396.                             </li>
  6397.                             <li class=\"ec-share__item\">
  6398.                                 <a href=\"https://social-plugins.line.me/lineit/share?url=";
  6399.         // line 4261
  6400.         echo twig_escape_filter($this->envtwig_urlencode_filter(twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["app"]) || array_key_exists("app"$context) ? $context["app"] : (function () { throw new RuntimeError('Variable "app" does not exist.'4261$this->source); })()), "request", [], "any"falsefalsefalse4261), "uri", [], "any"falsefalsefalse4261)), "html"nulltrue);
  6401.         echo "\" class=\"ec-share__link ec-share__link--line\" target=\"_blank\" rel=\"noreferrer noopener\">
  6402.                                     <i class=\"fab fa-line\"></i>
  6403.                                 </a>
  6404.                             </li>
  6405.                         </ul>
  6406.                     </div>
  6407.                 </div>
  6408. \t\t\t\t";
  6409.         // line 4269
  6410.         echo "\t\t\t\t<div id=\"sp-mitsumori-bar\">
  6411. \t\t\t\t    <div class=\"sp-bar__pricewrap\">
  6412. \t\t\t\t        <div class=\"sp-bar__label\">合計(工事費・税込)</div>
  6413. \t\t\t\t        <div class=\"sp-bar__price\" id=\"sp-mitsumori-price\">---円</div>
  6414. \t\t\t\t    </div>
  6415. \t\t\t\t    <button type=\"button\" class=\"sp-bar__btn\"
  6416. \t\t\t\t            onclick=\"document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">
  6417. \t\t\t\t        <i class=\"fas fa-shopping-cart\"></i>
  6418. \t\t\t\t        <span class=\"sp-bar__btn-label\">カートへ</span>
  6419. \t\t\t\t        ";
  6420.         // line 4278
  6421.         $context["spTotalQty"] = $this->extensions['Eccube\Twig\Extension\CartServiceExtension']->get_carts_total_quantity();
  6422.         // line 4279
  6423.         echo "\t\t\t\t        ";
  6424.         if (((isset($context["spTotalQty"]) || array_key_exists("spTotalQty"$context) ? $context["spTotalQty"] : (function () { throw new RuntimeError('Variable "spTotalQty" does not exist.'4279$this->source); })()) > 0)) {
  6425.             // line 4280
  6426.             echo "\t\t\t\t            <span class=\"sp-bar__cart-badge\">";
  6427.             echo twig_escape_filter($this->envtwig_number_format_filter($this->env, (isset($context["spTotalQty"]) || array_key_exists("spTotalQty"$context) ? $context["spTotalQty"] : (function () { throw new RuntimeError('Variable "spTotalQty" does not exist.'4280$this->source); })())), "html"nulltrue);
  6428.             echo "</span>
  6429. \t\t\t\t        ";
  6430.         }
  6431.         // line 4282
  6432.         echo "\t\t\t\t    </button>
  6433. \t\t\t\t    <a href=\"";
  6434.         // line 4283
  6435.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("homepage");
  6436.         echo "\" class=\"sp-bar__home-btn\" title=\"トップページへ\">
  6437. \t\t\t\t        <i class=\"fas fa-home\"></i>
  6438. \t\t\t\t    </a>
  6439. \t\t\t\t</div>
  6440. \t\t\t\t";
  6441.         // line 4289
  6442.         echo "\t\t\t\t<div id=\"tg-options\" class=\"tg-options-container col-12\"></div>
  6443. \t\t\t\t<div class=\"card col-12 collapsed-card sticky-top float-right mitsumori-card-pc\">
  6444. \t\t\t\t\t<div class=\"card-header\">
  6445. \t\t\t\t\t  <h3 class=\"card-title\">現在のお見積り額</h3>
  6446. \t\t\t\t\t  <div class=\"card-tools\">
  6447. \t\t\t\t\t    <span class=\"float-left\" id=\"mitsumori_message\">395000円</span>
  6448. \t\t\t\t\t    <button type=\"button\" class=\"btn btn-tool btn-mitsumori-toggle\" data-card-widget=\"collapse\" title=\"詳細を表示\">
  6449. \t\t\t\t\t      <span class=\"toggle-icon\">▼ 詳細</span>
  6450. \t\t\t\t\t    </button>
  6451. \t\t\t\t\t  </div>
  6452. \t\t\t\t\t</div>
  6453. \t\t\t\t\t<div class=\"card-body p-0\">
  6454. \t\t\t\t\t  <ul class=\"nav nav-pills flex-column\">
  6455. \t\t\t\t\t    <li class=\"nav-item active\">
  6456. \t\t\t\t\t      <a class=\"nav-link\">
  6457. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 合計(工事費・税込)
  6458. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_goukei\">395,000円</span>
  6459. \t\t\t\t\t      </a>
  6460. \t\t\t\t\t    </li>
  6461. \t\t\t\t\t    <li class=\"nav-item active\">
  6462. \t\t\t\t\t      <a class=\"nav-link\">
  6463. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 商品価格
  6464. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_price\">307,008円</span>
  6465. \t\t\t\t\t      </a>
  6466. \t\t\t\t\t    </li>
  6467. \t\t\t\t\t    ";
  6468.         // line 4316
  6469.         echo "\t\t\t\t\t    ";
  6470.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4316$this->source); })()), "SaleType", [], "any"falsefalsefalse4316), "id", [], "any"falsefalsefalse4316) != 2)) {
  6471.             // line 4317
  6472.             echo "\t\t\t\t\t    <li class=\"nav-item\">
  6473. \t\t\t\t\t      <a class=\"nav-link\">
  6474. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> カタログ価格
  6475. \t\t\t\t\t        <span class=\"float-right\" id=\"maker_price\">479,700円</span>
  6476. \t\t\t\t\t      </a>
  6477. \t\t\t\t\t    </li>
  6478. \t\t\t\t\t    ";
  6479.         } else {
  6480.             // line 4324
  6481.             echo "\t\t\t\t\t    ";
  6482.             // line 4325
  6483.             echo "\t\t\t\t\t    <span id=\"maker_price\" style=\"display:none;\">---円</span>
  6484. \t\t\t\t\t    ";
  6485.         }
  6486.         // line 4327
  6487.         echo "\t\t\t\t\t    <li class=\"nav-item\">
  6488. \t\t\t\t\t      <a class=\"nav-link\">
  6489. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i>
  6490. \t\t\t\t\t        ";
  6491.         // line 4330
  6492.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4330$this->source); })()), "SaleType", [], "any"falsefalsefalse4330), "id", [], "any"falsefalsefalse4330) == 2)) {
  6493.             echo "補助金(割引額)";
  6494.         } else {
  6495.             echo "お値引き";
  6496.         }
  6497.         // line 4331
  6498.         echo "\t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_off\">-172,692円</span>
  6499. \t\t\t\t\t      </a>
  6500. \t\t\t\t\t    </li>
  6501. \t\t\t\t\t    ";
  6502.         // line 4335
  6503.         echo "\t\t\t\t\t    ";
  6504.         if ((twig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source, (isset($context["ProductClass"]) || array_key_exists("ProductClass"$context) ? $context["ProductClass"] : (function () { throw new RuntimeError('Variable "ProductClass" does not exist.'4335$this->source); })()), "SaleType", [], "any"falsefalsefalse4335), "id", [], "any"falsefalsefalse4335) == 2)) {
  6505.             // line 4336
  6506.             echo "\t\t\t\t\t    <li class=\"nav-item\">
  6507. \t\t\t\t\t      <div style=\"padding:4px 12px 8px;color:#6c757d;font-size:11px;line-height:1.4;\">
  6508. \t\t\t\t\t        ※当店が補助金事業者として申請代行し、契約代金に充当します
  6509. \t\t\t\t\t      </div>
  6510. \t\t\t\t\t    </li>
  6511. \t\t\t\t\t    ";
  6512.         }
  6513.         // line 4342
  6514.         echo "\t\t\t\t\t    <li class=\"nav-item\">
  6515. \t\t\t\t\t      <a class=\"nav-link\">
  6516. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 基本工事費
  6517. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_ct\">53,250円</span>
  6518. \t\t\t\t\t      </a>
  6519. \t\t\t\t\t    </li>
  6520. \t\t\t\t\t    <li class=\"nav-item\">
  6521. \t\t\t\t\t      <a class=\"nav-link\">
  6522. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 施工オプション
  6523. \t\t\t\t\t        <span class=\"float-right\"id=\"mitsumori_option\">6,297円</span>
  6524. \t\t\t\t\t      </a>
  6525. \t\t\t\t\t    </li>
  6526. \t\t\t\t\t  </ul>
  6527. \t\t\t\t\t</div>
  6528. \t\t\t\t\t<div class=\"card-footer\">
  6529. \t\t                <button type=\"button\" id=\"mitsumori_btn\" class=\"btn btn-info\" data-toggle=\"modal\" data-target=\"#modal-mitsumori\">
  6530. \t\t                  見積書表示
  6531. \t\t                </button>
  6532.                         <button type=\"submit\" id=\"cart_btn2\" class=\"btn btn-info add-cart\">カートに入れる</button>
  6533. \t\t\t\t\t</div>
  6534. \t\t\t\t</div>
  6535.             </div>
  6536.         </div>
  6537.     </div>
  6538.   <div class=\"modal\" id=\"modal-mitsumori\">
  6539.     <div class=\"modal-dialog modal-mitsumori\" style=\"max-width:1000px\">
  6540.       <div class=\"modal-content\">
  6541.         <div class=\"modal-header\">
  6542.           <h4 class=\"modal-title\">お見積書</h4>
  6543.           <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">
  6544.             <span aria-hidden=\"true\">&times;</span>
  6545.           </button>
  6546.         </div>
  6547.         <div class=\"modal-body\">
  6548. \t\t\t<div class=\"invoice p-3 mb-5\" style=\"max-width:1000px; margin:auto;\">
  6549. \t\t\t  <!-- title row -->
  6550. \t\t\t  <div class=\"row\">
  6551. \t\t\t    <div class=\"col-12\">
  6552. \t\t\t      <h2>概算お見積書 
  6553. \t\t\t        <small class=\"float-right\" style=\"font-size:14px;\">発行日: 2025/03/14</small>
  6554. \t\t\t      </h2>
  6555. \t\t\t    </div>
  6556. \t\t\t    <!-- /.col -->
  6557. \t\t\t  </div>
  6558. \t\t\t  <!-- info row -->
  6559. \t\t\t  <div class=\"row invoice-info\">
  6560. \t\t\t    <div class=\"col-sm-8 invoice-col\">
  6561. \t\t\t      <h3>お客様</h3>
  6562. \t\t\t      <span>下記の通り、お見積もり申し上げます。</span>
  6563. \t\t\t      <br />
  6564. \t\t\t      <br / >
  6565. \t\t\t      <br />
  6566. \t\t\t      <h2>お見積金額: <span id=\"mitsumori_kei\">399,080円</span></h2>
  6567. \t\t\t      <span>
  6568. \t\t\t        <br/>
  6569. \t\t\t        <br/>
  6570. \t\t\t        <br/>
  6571. \t\t\t        <br/>
  6572. \t\t\t      </span>
  6573. \t\t\t    </div>
  6574. \t\t\t    <div class=\"col-sm-4 invoice-col\">
  6575. \t\t\t      <p>
  6576. \t\t\t        <img alt=\"\" src=\"/html/user_data/js/images/logo.png\" style=\"width: 260px; max-width: 100%; max-height: 10mm;\">
  6577. \t\t\t      </p>
  6578. \t\t\t      <p>有限会社プラス</p>
  6579. \t\t\t      <p>〒400-0334</p>
  6580. \t\t\t      <p>山梨県南アルプス市藤田1450番地2</p>
  6581. \t\t\t      <p>TEL: 055-284-6480</p>
  6582. \t\t\t      <img alt=\"\" src=\"/html/user_data/js/images/seal.svg\" style=\"z-index: 2; position: absolute; width: 21mm; left: 58mm; top: 36mm;\">
  6583. \t\t\t    </div>
  6584. \t\t\t    <!-- /.col -->
  6585. \t\t\t    <!-- /.col -->
  6586. \t\t\t  </div>
  6587. \t\t\t  <!-- /.row -->
  6588. \t\t\t  <!-- Table row -->
  6589. \t\t\t  <div class=\"row\">
  6590. \t\t\t    <div class=\"col-12 table-responsive\">
  6591. \t\t\t      <table class=\"table table-striped\">
  6592. \t\t\t        <thead>
  6593. \t\t\t          <tr>
  6594. \t\t\t            <th>項目</th>
  6595. \t\t\t            <th>数量</th>
  6596. \t\t\t            <th>単位</th>
  6597. \t\t\t            <th>単価</th>
  6598. \t\t\t            <th>小計</th>
  6599. \t\t\t          </tr>
  6600. \t\t\t        </thead>
  6601. \t\t\t        <tbody>
  6602. \t\t\t          <tr>
  6603. \t\t\t            <td id=\"mitsumori_item_name\">";
  6604.         // line 4435
  6605.         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["Product"]) || array_key_exists("Product"$context) ? $context["Product"] : (function () { throw new RuntimeError('Variable "Product" does not exist.'4435$this->source); })()), "name", [], "any"falsefalsefalse4435), "html"nulltrue);
  6606.         echo "</td>
  6607. \t\t\t            <td>1</td>
  6608. \t\t\t            <td>式</td>
  6609. \t\t\t            <td id=\"mitsumori_price_01\">352,800</td>
  6610. \t\t\t            <td id=\"mitsumori_price_02\">352,800</td>
  6611. \t\t\t          </tr>
  6612. \t\t\t          <tr>
  6613. \t\t\t            <td>基本工事費</td>
  6614. \t\t\t            <td>1</td>
  6615. \t\t\t            <td>式</td>
  6616. \t\t\t            <td id=\"mitsumori_ct_01\">10,000</td>
  6617. \t\t\t            <td id=\"mitsumori_ct_02\">10,000</td>
  6618. \t\t\t          </tr>
  6619. \t\t\t          <tr>
  6620. \t\t\t            <td>残土・ガラ処理</td>
  6621. \t\t\t            <td>1</td>
  6622. \t\t\t            <td>式</td>
  6623. \t\t\t            <td>0円</td>
  6624. \t\t\t            <td></td>
  6625. \t\t\t          </tr>
  6626. \t\t\t          <tr>
  6627. \t\t\t            <td> </td>
  6628. \t\t\t            <td></td>
  6629. \t\t\t            <td></td>
  6630. \t\t\t            <td></td>
  6631. \t\t\t            <td></td>
  6632. \t\t\t          </tr>
  6633. \t\t\t        </tbody>
  6634. \t\t\t      </table>
  6635. \t\t\t    </div>
  6636. \t\t\t    <!-- /.col -->
  6637. \t\t\t  </div>
  6638. \t\t\t  <!-- /.row -->
  6639. \t\t\t  <div class=\"row\">
  6640. \t\t\t    <!-- accepted payments column -->
  6641. \t\t\t    <div class=\"col-6\">
  6642. \t\t\t      <p class=\"lead\">お支払い方法</p>
  6643. \t\t\t      <p class=\"text-muted well well-sm shadow-none\" style=\"margin-top: 10px;\">銀行振込、クレジットカード決済、PAYPAY決済
  6644. \t\t\t        <br>銀行振込:山梨中央銀行 白根支店 普通口座 391402
  6645. \t\t\t        <br>※商品代金と工事代金の総額が金100万円(税込)を超える場合、着手金として代金の半額をご契約後お支払いいただきます。 
  6646. \t\t\t      </p>
  6647. \t\t\t    </div>
  6648. \t\t\t    <!-- /.col -->
  6649. \t\t\t    <div class=\"col-6\">
  6650. \t\t\t      <div class=\"table-responsive\">
  6651. \t\t\t        <table class=\"table\">
  6652. \t\t\t          <tbody>
  6653. \t\t\t            <tr>
  6654. \t\t\t              <th style=\"width:50%\">小計:</th>
  6655. \t\t\t              <td id=\"mitsumori_shoukei\">362,800</td>
  6656. \t\t\t            </tr>
  6657. \t\t\t            <tr>
  6658. \t\t\t              <th>消費税 (10%)</th>
  6659. \t\t\t              <td id=\"mitsumori_tax\">36,280</td>
  6660. \t\t\t            </tr>
  6661. \t\t\t            <tr>
  6662. \t\t\t              <th>合計:</th>
  6663. \t\t\t              <td id=\"mitsumori_goukei_02\">399,080</td>
  6664. \t\t\t            </tr>
  6665. \t\t\t          </tbody>
  6666. \t\t\t        </table>
  6667. \t\t\t      </div>
  6668. \t\t\t    </div>
  6669. \t\t\t    <!-- /.col -->
  6670. \t\t\t  </div>
  6671. \t\t\t  <!-- /.row -->
  6672. \t\t\t</div>
  6673.         </div>
  6674.         <div class=\"modal-footer justify-content-between\">
  6675. \t\t\t      ";
  6676.         // line 4505
  6677.         echo "\t\t\t      <form method=\"post\" action=\"";
  6678.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("mitsumori_pdf");
  6679.         echo "\" target=\"_blank\" id=\"pdf_download_form\">
  6680. \t\t\t        <input type=\"hidden\" name=\"_token\" value=\"";
  6681.         // line 4506
  6682.         echo twig_escape_filter($this->env$this->env->getRuntime('Symfony\Component\Form\FormRenderer')->renderCsrfToken("mitsumori_pdf"), "html"nulltrue);
  6683.         echo "\">
  6684. \t\t\t        <input type=\"hidden\" name=\"mitsumori_json\" id=\"pdf_mitsumori_json\">
  6685. \t\t\t        <button type=\"submit\" class=\"btn btn-primary float-right\" style=\"margin-right: 5px;\" onclick=\"syncPdfJson();\">
  6686. \t\t\t          <i class=\"fas fa-download\"></i>PDF出力
  6687. \t\t\t        </button>
  6688. \t\t\t      </form>
  6689.                   <button type=\"submit\" id=\"cart_btn3\" class=\"btn btn-info add-cart\">カートに入れる</button>
  6690.         </div>
  6691.       </div>
  6692.       <!-- /.modal-content -->
  6693.     </div>
  6694.     <!-- /.modal-dialog -->
  6695.   </div>
  6696.   <!-- /.modal -->
  6697.     <!-- Image zoom modal: custom lightweight lightbox (no CDN dependency) -->
  6698.     <div id=\"img-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"画像拡大\">
  6699.         <button id=\"img-modal__close\" aria-label=\"閉じる\">&times;</button>
  6700.         <button id=\"img-modal__prev\" aria-label=\"前の画像\">&#10094;</button>
  6701.         <img id=\"img-modal__img\" src=\"\" alt=\"\">
  6702.         <button id=\"img-modal__next\" aria-label=\"次の画像\">&#10095;</button>
  6703.     </div>
  6704.     <style>
  6705.     #img-modal {
  6706.         display: none;
  6707.         position: fixed;
  6708.         inset: 0;
  6709.         z-index: 9999;
  6710.         background: rgba(0,0,0,0.88);
  6711.         align-items: center;
  6712.         justify-content: center;
  6713.         cursor: zoom-out;
  6714.     }
  6715.     #img-modal.is-open { display: flex; }
  6716.     #img-modal__img {
  6717.         max-width: 92vw;
  6718.         max-height: 88vh;
  6719.         object-fit: contain;
  6720.         border-radius: 4px;
  6721.         cursor: default;
  6722.         user-select: none;
  6723.         touch-action: pinch-zoom;
  6724.         display: block;
  6725.     }
  6726.     #img-modal__close {
  6727.         position: absolute;
  6728.         top: 14px;
  6729.         right: 18px;
  6730.         font-size: 38px;
  6731.         color: #fff;
  6732.         cursor: pointer;
  6733.         background: none;
  6734.         border: none;
  6735.         padding: 0;
  6736.         line-height: 1;
  6737.         z-index: 1;
  6738.         opacity: 0.85;
  6739.     }
  6740.     #img-modal__close:hover { opacity: 1; }
  6741.     #img-modal__prev,
  6742.     #img-modal__next {
  6743.         position: absolute;
  6744.         top: 50%;
  6745.         transform: translateY(-50%);
  6746.         font-size: 36px;
  6747.         color: #fff;
  6748.         cursor: pointer;
  6749.         background: rgba(0,0,0,0.32);
  6750.         border: none;
  6751.         padding: 10px 16px;
  6752.         line-height: 1;
  6753.         border-radius: 6px;
  6754.         z-index: 1;
  6755.         opacity: 0.8;
  6756.         user-select: none;
  6757.     }
  6758.     #img-modal__prev:hover, #img-modal__next:hover { opacity: 1; }
  6759.     #img-modal__prev { left: 12px; }
  6760.     #img-modal__next { right: 12px; }
  6761.     @media (max-width: 767px) {
  6762.         #img-modal__prev, #img-modal__next { font-size: 28px; padding: 8px 12px; }
  6763.     }
  6764.     </style>
  6765.     <script>
  6766.     (function(){
  6767.         var images = [];
  6768.         var current = 0;
  6769.         // Collect original (non-cloned) slide images at click time.
  6770.         // After Slick init, slides are wrapped in .slick-slide; clones have .slick-cloned.
  6771.         function collectImages() {
  6772.             images = [];
  6773.             var \$slides = \$('.item_visual .slick-slide:not(.slick-cloned)');
  6774.             if (!\$slides.length) {
  6775.                 // Slick not yet initialized (fallback)
  6776.                 \$slides = \$('.item_visual .slide-item');
  6777.             }
  6778.             \$slides.each(function() {
  6779.                 var \$a = \$(this).find('a.js-zoom');
  6780.                 if (\$a.length) {
  6781.                     images.push({ src: \$a.attr('href'), alt: \$a.find('img').attr('alt') || '' });
  6782.                 }
  6783.             });
  6784.         }
  6785.         function showImage(idx) {
  6786.             current = ((idx % images.length) + images.length) % images.length;
  6787.             \$('#img-modal__img').attr({ src: images[current].src, alt: images[current].alt });
  6788.         }
  6789.         function openModal(href) {
  6790.             collectImages();
  6791.             if (!images.length) return;
  6792.             var idx = 0;
  6793.             for (var i = 0; i < images.length; i++) {
  6794.                 if (images[i].src === href) { idx = i; break; }
  6795.             }
  6796.             showImage(idx);
  6797.             \$('#img-modal').addClass('is-open');
  6798.             \$('body').css('overflow', 'hidden');
  6799.         }
  6800.         function closeModal() {
  6801.             \$('#img-modal').removeClass('is-open');
  6802.             \$('body').css('overflow', '');
  6803.         }
  6804.         // Click handler: works for both original and Slick-cloned anchors
  6805.         \$(document).on('click', '.item_visual a.js-zoom', function(e) {
  6806.             e.preventDefault();
  6807.             openModal(\$(this).attr('href'));
  6808.         });
  6809.         // Close on backdrop click
  6810.         \$('#img-modal').on('click', function(e) {
  6811.             if (e.target === this) closeModal();
  6812.         });
  6813.         \$('#img-modal__close').on('click', closeModal);
  6814.         \$('#img-modal__prev').on('click', function(e) { e.stopPropagation(); showImage(current - 1); });
  6815.         \$('#img-modal__next').on('click', function(e) { e.stopPropagation(); showImage(current + 1); });
  6816.         // Keyboard navigation
  6817.         \$(document).on('keydown', function(e) {
  6818.             if (!\$('#img-modal').hasClass('is-open')) return;
  6819.             if (e.key === 'Escape') closeModal();
  6820.             if (e.key === 'ArrowLeft') showImage(current - 1);
  6821.             if (e.key === 'ArrowRight') showImage(current + 1);
  6822.         });
  6823.         // Touch swipe (horizontal only)
  6824.         var _tx = 0;
  6825.         var \$modal = document.getElementById('img-modal');
  6826.         \$modal.addEventListener('touchstart', function(e) {
  6827.             _tx = e.changedTouches[0].clientX;
  6828.         }, { passive: true });
  6829.         \$modal.addEventListener('touchend', function(e) {
  6830.             var dx = e.changedTouches[0].clientX - _tx;
  6831.             if (Math.abs(dx) > 48) {
  6832.                 dx < 0 ? showImage(current + 1) : showImage(current - 1);
  6833.             }
  6834.         }, { passive: true });
  6835.     })();
  6836.     </script>
  6837. ";
  6838.         
  6839.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  6840.         
  6841.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  6842.     }
  6843.     public function getTemplateName()
  6844.     {
  6845.         return "Product/detail.twig";
  6846.     }
  6847.     public function isTraitable()
  6848.     {
  6849.         return false;
  6850.     }
  6851.     public function getDebugInfo()
  6852.     {
  6853.         return array (  6928 => 4506,  6923 => 4505,  6851 => 4435,  6756 => 4342,  6748 => 4336,  6745 => 4335,  6740 => 4331,  6734 => 4330,  6729 => 4327,  6725 => 4325,  6723 => 4324,  6714 => 4317,  6711 => 4316,  6683 => 4289,  6675 => 4283,  6672 => 4282,  6666 => 4280,  6663 => 4279,  6661 => 4278,  6650 => 4269,  6640 => 4261,  6632 => 4256,  6622 => 4251,  6617 => 4248,  6611 => 4244,  6602 => 4238,  6596 => 4237,  6590 => 4234,  6586 => 4233,  6578 => 4228,  6573 => 4225,  6566 => 4221,  6562 => 4219,  6554 => 4214,  6550 => 4213,  6547 => 4212,  6544 => 4211,  6538 => 4208,  6534 => 4207,  6531 => 4206,  6529 => 4205,  6524 => 4203,  6520 => 4202,  6517 => 4201,  6515 => 4200,  6512 => 4199,  6510 => 4198,  6506 => 4197,  6498 => 4191,  6494 => 4189,  6491 => 4188,  6488 => 4184,  6482 => 4183,  6479 => 4182,  6476 => 4181,  6472 => 4179,  6460 => 4175,  6458 => 4174,  6455 => 4173,  6449 => 4170,  6437 => 4169,  6431 => 4168,  6424 => 4167,  6422 => 4166,  6417 => 4164,  6405 => 4163,  6399 => 4162,  6392 => 4161,  6389 => 4158,  6383 => 4157,  6374 => 4156,  6366 => 4154,  6363 => 4153,  6361 => 4152,  6359 => 4151,  6357 => 4150,  6355 => 4148,  6352 => 4147,  6349 => 4146,  6346 => 4145,  6343 => 4144,  6340 => 4143,  6337 => 4142,  6334 => 4141,  6331 => 4140,  6328 => 4139,  6325 => 4138,  6320 => 4137,  6317 => 4136,  6311 => 4135,  6306 => 4134,  6301 => 4133,  6296 => 4132,  6293 => 4131,  6290 => 4130,  6287 => 4129,  6280 => 4121,  6264 => 4107,  6262 => 4106,  6258 => 4104,  6244 => 4093,  6237 => 4088,  6235 => 4087,  6233 => 4086,  6229 => 4084,  6217 => 4075,  6213 => 4073,  6208 => 4070,  6200 => 4064,  6191 => 4058,  6183 => 4052,  6180 => 4049,  6169 => 4046,  6166 => 4045,  6163 => 4044,  6160 => 4043,  6157 => 4041,  6152 => 4038,  6142 => 4035,  6136 => 4034,  6130 => 4033,  6126 => 4032,  6119 => 4031,  6112 => 4030,  6110 => 4029,  6101 => 4027,  6098 => 4026,  6095 => 4025,  6092 => 4022,  6087 => 4019,  6077 => 4016,  6071 => 4015,  6065 => 4014,  6061 => 4013,  6054 => 4012,  6047 => 4011,  6045 => 4010,  6036 => 4008,  6033 => 4007,  6030 => 4006,  6027 => 4004,  6025 => 4003,  6021 => 4001,  6010 => 3995,  6001 => 3991,  5993 => 3988,  5985 => 3985,  5976 => 3982,  5973 => 3981,  5971 => 3980,  5966 => 3977,  5956 => 3971,  5947 => 3967,  5939 => 3964,  5931 => 3961,  5922 => 3958,  5919 => 3957,  5917 => 3956,  5912 => 3953,  5909 => 3951,  5907 => 3950,  5903 => 3948,  5889 => 3937,  5883 => 3933,  5880 => 3931,  5878 => 3930,  5874 => 3928,  5860 => 3917,  5854 => 3913,  5851 => 3911,  5846 => 3908,  5836 => 3905,  5830 => 3904,  5824 => 3903,  5820 => 3902,  5813 => 3901,  5806 => 3900,  5804 => 3899,  5795 => 3897,  5792 => 3896,  5789 => 3895,  5786 => 3893,  5781 => 3890,  5771 => 3887,  5765 => 3886,  5759 => 3885,  5755 => 3884,  5748 => 3883,  5741 => 3882,  5739 => 3881,  5729 => 3879,  5726 => 3878,  5723 => 3877,  5720 => 3875,  5715 => 3872,  5705 => 3869,  5699 => 3868,  5693 => 3867,  5689 => 3866,  5682 => 3865,  5675 => 3864,  5673 => 3863,  5664 => 3861,  5661 => 3860,  5658 => 3859,  5655 => 3857,  5650 => 3854,  5640 => 3851,  5634 => 3850,  5628 => 3849,  5624 => 3848,  5617 => 3847,  5610 => 3846,  5608 => 3845,  5599 => 3843,  5596 => 3842,  5594 => 3841,  5591 => 3840,  5586 => 3837,  5576 => 3834,  5570 => 3833,  5564 => 3832,  5560 => 3831,  5553 => 3830,  5546 => 3829,  5544 => 3828,  5535 => 3826,  5532 => 3825,  5530 => 3824,  5527 => 3823,  5522 => 3820,  5512 => 3817,  5506 => 3816,  5500 => 3815,  5496 => 3814,  5489 => 3813,  5482 => 3812,  5480 => 3811,  5471 => 3809,  5468 => 3808,  5465 => 3807,  5462 => 3805,  5460 => 3804,  5456 => 3802,  5326 => 3674,  5309 => 3658,  5306 => 3656,  5301 => 3653,  5293 => 3651,  5287 => 3649,  5282 => 3647,  5274 => 3645,  5272 => 3644,  5268 => 3643,  5261 => 3642,  5258 => 3641,  5253 => 3640,  5248 => 3637,  5245 => 3636,  5242 => 3634,  5236 => 3630,  5226 => 3627,  5222 => 3626,  5219 => 3625,  5214 => 3624,  5209 => 3621,  5206 => 3620,  5203 => 3618,  5195 => 3615,  5185 => 3607,  5182 => 3606,  5179 => 3604,  5171 => 3601,  5161 => 3593,  5158 => 3592,  5155 => 3590,  5150 => 3587,  5140 => 3584,  5136 => 3583,  5133 => 3582,  5128 => 3581,  5123 => 3578,  5120 => 3577,  5111 => 3569,  5086 => 3548,  5076 => 3543,  5065 => 3534,  5062 => 3533,  5052 => 3524,  5049 => 3520,  5046 => 3516,  5044 => 3515,  5040 => 3513,  5037 => 3512,  5035 => 3511,  5031 => 3509,  5026 => 3506,  5016 => 3503,  5010 => 3502,  5004 => 3501,  5000 => 3500,  4993 => 3499,  4986 => 3498,  4984 => 3497,  4974 => 3495,  4971 => 3494,  4968 => 3493,  4965 => 3491,  4960 => 3488,  4950 => 3485,  4944 => 3484,  4938 => 3483,  4934 => 3482,  4927 => 3481,  4920 => 3480,  4918 => 3479,  4908 => 3477,  4905 => 3476,  4902 => 3475,  4899 => 3470,  4894 => 3467,  4884 => 3464,  4878 => 3463,  4872 => 3462,  4868 => 3461,  4861 => 3460,  4854 => 3459,  4852 => 3458,  4843 => 3456,  4840 => 3455,  4837 => 3454,  4834 => 3452,  4829 => 3449,  4819 => 3446,  4813 => 3445,  4807 => 3444,  4803 => 3443,  4796 => 3442,  4789 => 3441,  4787 => 3440,  4778 => 3438,  4775 => 3437,  4772 => 3436,  4769 => 3433,  4764 => 3430,  4754 => 3427,  4748 => 3426,  4742 => 3425,  4738 => 3424,  4731 => 3423,  4724 => 3422,  4722 => 3421,  4713 => 3419,  4710 => 3418,  4708 => 3417,  4705 => 3416,  4700 => 3413,  4690 => 3410,  4684 => 3409,  4678 => 3408,  4674 => 3407,  4667 => 3406,  4660 => 3405,  4658 => 3404,  4649 => 3402,  4646 => 3401,  4643 => 3400,  4640 => 3395,  4635 => 3392,  4627 => 3390,  4621 => 3388,  4616 => 3386,  4608 => 3384,  4606 => 3383,  4600 => 3382,  4594 => 3381,  4590 => 3380,  4580 => 3379,  4577 => 3378,  4570 => 3377,  4568 => 3376,  4559 => 3374,  4556 => 3373,  4553 => 3372,  4550 => 3370,  4546 => 3368,  4543 => 3367,  4541 => 3365,  4540 => 3364,  4539 => 3363,  4538 => 3362,  4537 => 3361,  4536 => 3360,  4535 => 3359,  4534 => 3358,  4532 => 3357,  4529 => 3356,  4523 => 3355,  4520 => 3354,  4515 => 3353,  4510 => 3352,  4505 => 3351,  4502 => 3350,  4499 => 3349,  4494 => 3348,  4491 => 3347,  4488 => 3346,  4485 => 3345,  4479 => 3344,  4474 => 3343,  4469 => 3342,  4464 => 3341,  4461 => 3340,  4458 => 3339,  4455 => 3338,  4451 => 3329,  4447 => 3327,  4443 => 3325,  4434 => 3322,  4425 => 3321,  4421 => 3320,  4418 => 3319,  4416 => 3318,  4412 => 3316,  4403 => 3313,  4399 => 3312,  4395 => 3311,  4385 => 3309,  4381 => 3308,  4378 => 3307,  4376 => 3306,  4374 => 3305,  4365 => 3304,  4362 => 3303,  4359 => 3302,  4356 => 3300,  4352 => 3298,  4348 => 3296,  4339 => 3293,  4330 => 3292,  4326 => 3291,  4323 => 3290,  4319 => 3288,  4310 => 3285,  4303 => 3281,  4299 => 3280,  4289 => 3278,  4285 => 3277,  4282 => 3276,  4280 => 3275,  4271 => 3274,  4268 => 3273,  4265 => 3272,  4262 => 3270,  4258 => 3268,  4254 => 3266,  4245 => 3263,  4236 => 3262,  4232 => 3261,  4229 => 3260,  4225 => 3258,  4216 => 3255,  4209 => 3251,  4205 => 3250,  4195 => 3248,  4191 => 3247,  4188 => 3246,  4186 => 3245,  4177 => 3244,  4174 => 3243,  4171 => 3242,  4168 => 3240,  4164 => 3238,  4160 => 3236,  4151 => 3233,  4142 => 3232,  4138 => 3231,  4135 => 3230,  4133 => 3229,  4129 => 3227,  4120 => 3224,  4113 => 3220,  4109 => 3219,  4099 => 3217,  4095 => 3216,  4092 => 3215,  4090 => 3214,  4088 => 3213,  4079 => 3212,  4076 => 3211,  4073 => 3210,  4070 => 3208,  4066 => 3206,  4063 => 3205,  4061 => 3204,  4060 => 3203,  4059 => 3202,  4057 => 3201,  4054 => 3200,  4051 => 3199,  4048 => 3198,  4045 => 3197,  4042 => 3196,  4039 => 3195,  4036 => 3194,  4033 => 3193,  4031 => 3192,  4029 => 3191,  4017 => 3182,  4010 => 3177,  3998 => 3174,  3995 => 3173,  3992 => 3172,  3989 => 3170,  3978 => 3168,  3974 => 3167,  3971 => 3166,  3968 => 3164,  3962 => 3161,  3958 => 3160,  3955 => 3159,  3952 => 3158,  3946 => 3155,  3940 => 3154,  3937 => 3153,  3931 => 3150,  3927 => 3149,  3924 => 3148,  3922 => 3147,  3920 => 3146,  3916 => 3144,  3914 => 3143,  3910 => 3141,  3904 => 3140,  3899 => 3137,  3884 => 3135,  3875 => 3134,  3858 => 3133,  3854 => 3131,  3851 => 3130,  3847 => 3129,  3844 => 3128,  3841 => 3127,  3838 => 3126,  3825 => 3115,  3811 => 3103,  3805 => 3098,  3786 => 3096,  3769 => 3095,  3765 => 3093,  3754 => 3091,  3731 => 3087,  3725 => 3086,  3722 => 3085,  3704 => 3084,  3701 => 3083,  3697 => 3081,  3689 => 3077,  3681 => 3073,  3679 => 3072,  3676 => 3071,  3674 => 3070,  3664 => 3063,  3652 => 3056,  3647 => 3054,  3643 => 3052,  3637 => 3047,  3634 => 3046,  3628 => 3045,  3623 => 3044,  3618 => 3043,  3612 => 3042,  3606 => 3041,  3601 => 3040,  3598 => 3039,  3595 => 3038,  3592 => 3037,  3590 => 3036,  3580 => 3035,  3564 => 3028,  3560 => 3027,  3556 => 3026,  3552 => 3025,  3548 => 3023,  3542 => 3021,  3540 => 3020,  3535 => 3019,  3532 => 3018,  3522 => 3016,  3508 => 3014,  3500 => 3013,  3482 => 3012,  3477 => 3010,  3376 => 2916,  3368 => 2915,  3304 => 2854,  3204 => 2757,  3200 => 2756,  3184 => 2743,  3016 => 2577,  3013 => 2576,  3000 => 2575,  2997 => 2574,  2995 => 2573,  2992 => 2572,  2989 => 2571,  2976 => 2570,  2973 => 2569,  2970 => 2568,  2967 => 2566,  2964 => 2565,  2951 => 2564,  2948 => 2563,  2946 => 2562,  2943 => 2561,  2940 => 2560,  2927 => 2559,  2924 => 2558,  2922 => 2557,  2919 => 2556,  2916 => 2555,  2903 => 2554,  2900 => 2553,  2898 => 2552,  2895 => 2551,  2892 => 2550,  2879 => 2549,  2876 => 2548,  2874 => 2547,  2871 => 2546,  2868 => 2545,  2855 => 2544,  2852 => 2543,  2849 => 2542,  2846 => 2541,  2832 => 2540,  2829 => 2539,  2816 => 2538,  2813 => 2537,  2810 => 2536,  2717 => 2442,  2297 => 2025,  1940 => 1671,  1909 => 1643,  1896 => 1633,  1867 => 1607,  1863 => 1606,  1855 => 1601,  1406 => 1154,  1403 => 1153,  1397 => 1152,  1392 => 1151,  1387 => 1150,  1381 => 1149,  1375 => 1148,  1370 => 1147,  1367 => 1146,  1364 => 1145,  1361 => 1144,  1356 => 1141,  1343 => 1131,  1329 => 1120,  1301 => 1097,  1295 => 1096,  1289 => 1095,  1283 => 1094,  1277 => 1093,  1271 => 1092,  1265 => 1091,  1259 => 1090,  1253 => 1089,  1247 => 1088,  1241 => 1087,  1235 => 1086,  1229 => 1085,  1222 => 1083,  1216 => 1082,  1210 => 1081,  1204 => 1080,  1198 => 1079,  1178 => 1062,  1168 => 1055,  1138 => 1028,  1126 => 1018,  1117 => 1012,  1113 => 1010,  1111 => 1009,  1108 => 1008,  1099 => 1002,  1095 => 1000,  1093 => 999,  1021 => 929,  1013 => 927,  1011 => 926,  1006 => 924,  1003 => 923,  1001 => 922,  987 => 911,  983 => 909,  973 => 908,  73 => 16,  63 => 15,  52 => 11,  50 => 13,  37 => 11,);
  6854.     }
  6855.     public function getSourceContext()
  6856.     {
  6857.         return new Source("{#
  6858. This file is part of EC-CUBE
  6859. Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6860. http://www.ec-cube.co.jp/
  6861. For the full copyright and license information, please view the LICENSE
  6862. file that was distributed with this source code.
  6863. #}
  6864. {% extends 'default_frame.twig' %}
  6865. {% set body_class = 'product_page' %}
  6866. {% block stylesheet %}
  6867.     <style>
  6868.         .slick-slider {
  6869.             margin-bottom: 10px;
  6870. \t\t\tmargin-top: -20px;
  6871.         }
  6872.         .slick-dots {
  6873.             position: absolute;
  6874.             bottom: -45px;
  6875.             display: block;
  6876.             width: 100%;
  6877.             padding: 0;
  6878.             list-style: none;
  6879.             text-align: center;
  6880.         }
  6881.         .slick-dots li {
  6882.             position: relative;
  6883.             display: inline-block;
  6884.             width: 20px;
  6885.             height: 20px;
  6886.             margin: 0 5px;
  6887.             padding: 0;
  6888.             cursor: pointer;
  6889.         }
  6890.         .slick-dots li button {
  6891.             font-size: 0;
  6892.             line-height: 0;
  6893.             display: block;
  6894.             width: 20px;
  6895.             height: 20px;
  6896.             padding: 5px;
  6897.             cursor: pointer;
  6898.             color: transparent;
  6899.             border: 0;
  6900.             outline: none;
  6901.             background: transparent;
  6902.         }
  6903.         .slick-dots li button:hover,
  6904.         .slick-dots li button:focus {
  6905.             outline: none;
  6906.         }
  6907.         .slick-dots li button:hover:before,
  6908.         .slick-dots li button:focus:before {
  6909.             opacity: 1;
  6910.         }
  6911.         .slick-dots li button:before {
  6912.             content: \" \";
  6913.             line-height: 20px;
  6914.             position: absolute;
  6915.             top: 0;
  6916.             left: 0;
  6917.             width: 12px;
  6918.             height: 12px;
  6919.             text-align: center;
  6920.             opacity: .25;
  6921.             background-color: black;
  6922.             border-radius: 50%;
  6923.         }
  6924.         .slick-dots li.slick-active button:before {
  6925.             opacity: .75;
  6926.             background-color: black;
  6927.         }
  6928.         .slick-dots li button.thumbnail img {
  6929.             width: 0;
  6930.             height: 0;
  6931.         }
  6932.     </style>
  6933.     <link rel=\"stylesheet\" href=\"/html/user_data/js/style.css\">
  6934.     <link rel=\"stylesheet\" href=\"/html/plugins/icheck-bootstrap/icheck-bootstrap.min.css\">
  6935.     <style>
  6936.         /* Show zoom cursor on product images to hint click-to-expand */
  6937.         .item_visual .slide-item a { display: block; cursor: zoom-in; }
  6938.     </style>
  6939.     <style>
  6940.         /* ============================================
  6941.            商品詳細グリッド: 画像50% / 内容50%(均等)
  6942.         ============================================ */
  6943.         @media (min-width: 768px) {
  6944.             body.product_page .ec-grid2 {
  6945.                 display: flex;
  6946.                 align-items: flex-start;
  6947.             }
  6948.             body.product_page .ec-grid2 .ec-grid2__cell {
  6949.                 width: 50%;
  6950.                 flex: 0 0 50%;
  6951.                 min-width: 0;
  6952.             }
  6953.             body.product_page .ec-grid2 .ec-grid2__cell2 {
  6954.                 width: 50%;
  6955.                 flex: 0 0 50%;
  6956.                 min-width: 0;
  6957.             }
  6958.         }
  6959.         /* ============================================
  6960.            商品説明欄内のHTMLが画面幅を突き抜けないように
  6961.         ============================================ */
  6962.         body.product_page .ec-productRole__description {
  6963.             min-width: 0;
  6964.             overflow-wrap: break-word;
  6965.             word-break: break-word;
  6966.         }
  6967.         body.product_page .ec-productRole__description img,
  6968.         body.product_page .ec-productRole__description table,
  6969.         body.product_page .ec-productRole__description iframe,
  6970.         body.product_page .ec-productRole__description video {
  6971.             max-width: 100% !important;
  6972.             height: auto;
  6973.         }
  6974.         body.product_page .ec-productRole__description table {
  6975.             display: block;
  6976.             overflow-x: auto;
  6977.             -webkit-overflow-scrolling: touch;
  6978.         }
  6979.         /* ============================================
  6980.            スマホ用 見積金額 下部固定バー
  6981.         ============================================ */
  6982.         #sp-mitsumori-bar {
  6983.             display: none;
  6984.         }
  6985.         
  6986.         /* ============================================
  6987.            商品タイプ選択 共通スタイル
  6988.         ============================================ */
  6989.         /* セクションラベル */
  6990.         .rp-section-label {
  6991.             font-size: 14px;
  6992.             font-weight: bold;
  6993.             color: #333;
  6994.             margin-bottom: 10px;
  6995.         }
  6996.         .rp-section-label span {
  6997.             font-weight: normal;
  6998.             color: #c00;
  6999.         }
  7000.         /* ---- 1. 画像付きカード ---- */
  7001.         .rp-card-group {
  7002.             display: flex;
  7003.             flex-wrap: wrap;
  7004.             gap: 8px;
  7005.             margin-bottom: 4px;
  7006.         }
  7007.         .rp-card {
  7008.             position: relative;
  7009.             cursor: pointer;
  7010.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7011.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7012.             width: 110px;
  7013.             border: 2px solid #ddd;
  7014.             border-radius: 10px;
  7015.             overflow: hidden;
  7016.             transition: border-color 0.2s, box-shadow 0.2s;
  7017.             background: #fff;
  7018.             text-decoration: none;
  7019.             color: #333;
  7020.             display: block;
  7021.         }
  7022.         /* Gate :hover behind real hover-capable pointers. On iOS Safari a
  7023.            :hover rule that changes appearance makes the first tap apply the
  7024.            hover state and suppresses the click, so the option chip needed a
  7025.            second tap to fire its onclick (is-selected + price update). */
  7026.         @media (hover: hover) and (pointer: fine) {
  7027.             .rp-card:hover {
  7028.                 border-color: #999;
  7029.                 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  7030.             }
  7031.         }
  7032.         .rp-card.is-selected {
  7033.             border-color: #1a6fcf;
  7034.             box-shadow: 0 2px 10px rgba(26,111,207,0.25);
  7035.         }
  7036.         /* visually-hidden instead of display:none. A label wrapping a
  7037.            display:none radio fires its tap unreliably on iOS Safari (first tap
  7038.            often ignored -> \"2回タッチ\"). Keeping the input in the layout but
  7039.            invisible makes the first tap register. */
  7040.         .rp-card input[type=\"radio\"] {
  7041.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7042.             margin: 0; pointer-events: none;
  7043.         }
  7044.         .rp-card__image {
  7045.             width: 100%;
  7046.             aspect-ratio: 1 / 1;
  7047.             object-fit: cover;
  7048.             display: block;
  7049.             background: #f5f5f5;
  7050.         }
  7051.         .rp-card__placeholder {
  7052.             width: 100%;
  7053.             aspect-ratio: 1 / 1;
  7054.             background: #f0f0f0;
  7055.             display: flex;
  7056.             align-items: center;
  7057.             justify-content: center;
  7058.             color: #bbb;
  7059.             font-size: 24px;
  7060.         }
  7061.         .rp-card__name {
  7062.             display: block;
  7063.             padding: 5px 5px;
  7064.             font-size: 11px;
  7065.             color: #333;
  7066.             text-align: center;
  7067.             line-height: 1.4;
  7068.             word-break: break-all;
  7069.         }
  7070.         .rp-card.is-selected .rp-card__name { color: #1a6fcf; font-weight: bold; }
  7071.         .rp-card.is-selected::after {
  7072.             content: \"✓\";
  7073.             position: absolute;
  7074.             top: 3px; right: 6px;
  7075.             color: #1a6fcf;
  7076.             font-size: 13px;
  7077.             font-weight: bold;
  7078.         }
  7079.         /* ---- 2. ボタン式ラジオ(画像なし・8個以内)---- */
  7080.         .rp-btn-group {
  7081.             display: flex;
  7082.             flex-wrap: wrap;
  7083.             gap: 8px;
  7084.             margin-bottom: 4px;
  7085.             max-width: 100%;
  7086.             min-width: 0;
  7087.         }
  7088.         .rp-btn {
  7089.             cursor: pointer;
  7090.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7091.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7092.             padding: 8px 14px;
  7093.             border: 2px solid #ddd;
  7094.             border-radius: 10px;
  7095.             font-size: 13px;
  7096.             color: #333;
  7097.             background: #fff;
  7098.             transition: border-color 0.2s, background 0.2s;
  7099.             white-space: normal;
  7100.             max-width: 100%;
  7101.             overflow-wrap: anywhere;
  7102.             text-decoration: none;
  7103.         }
  7104.         @media (hover: hover) and (pointer: fine) {
  7105.             .rp-btn:hover { border-color: #999; }
  7106.         }
  7107.         .rp-btn.is-selected {
  7108.             border-color: #1a6fcf;
  7109.             color: #1a6fcf;
  7110.             font-weight: bold;
  7111.             background: #f0f6ff;
  7112.         }
  7113.         .rp-btn input[type=\"radio\"] {
  7114.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7115.             margin: 0; pointer-events: none;
  7116.         }
  7117.         /* iOS Safari \"2回タッチ\" fix for the type-selection link chips.
  7118.            The global theme stylesheet ships an ungated `a:hover{color:#296292}`
  7119.            (paired with `a{color:#337ab7;text-decoration:underline}`). Because
  7120.            .rp-btn / .rp-card are real <a> links, iOS Safari applies that hover
  7121.            colour on the FIRST tap — the chip text turns blue (#296292, the
  7122.            reported \"字だけ青くなる\") — and treats the tap as a hover, swallowing
  7123.            the navigation so a 2nd tap was needed. The local .rp-*:hover rules
  7124.            are already gated behind (hover:hover), but this inherited global
  7125.            rule was not. Pin the hover/active colour to the base/selected colour
  7126.            so tapping produces no visual change and the first tap navigates
  7127.            immediately. Higher specificity (0,2,0 / 0,3,0) overrides a:hover. */
  7128.         .rp-btn:hover,
  7129.         .rp-btn:active { color: #333; text-decoration: none; }
  7130.         .rp-btn.is-selected:hover,
  7131.         .rp-btn.is-selected:active { color: #1a6fcf; text-decoration: none; }
  7132.         .rp-card:hover,
  7133.         .rp-card:active { color: #333; text-decoration: none; }
  7134.         .rp-card:hover .rp-card__name,
  7135.         .rp-card:active .rp-card__name { color: #333; }
  7136.         .rp-card.is-selected:hover .rp-card__name,
  7137.         .rp-card.is-selected:active .rp-card__name { color: #1a6fcf; }
  7138.         /* ---- 選択肢が多い場合: 縦3段に収めて横スクロール(顧客要望「3列くらいで横スクロール」)---- */
  7139.         /* grid-auto-flow:column + 3行固定 → 選択肢が縦に最大3段、超過分は右へ伸び横スクロールで閲覧 */
  7140.         .rp-btn-group.is-scroll,
  7141.         .opt-btn-group.is-scroll {
  7142.             display: grid;
  7143.             grid-auto-flow: column;
  7144.             grid-template-rows: repeat(3, auto);
  7145.             grid-auto-columns: max-content;
  7146.             justify-content: start;
  7147.             align-items: start;
  7148.             gap: 8px;
  7149.             overflow-x: auto;
  7150.             overflow-y: hidden;
  7151.             -webkit-overflow-scrolling: touch;
  7152.             scrollbar-width: thin;
  7153.             /* 上下に余白を確保して、行の枠線が overflow クリップ/スクロールバーに
  7154.                切り取られないようにする(「文字列が長いと下枠が消える」対策)。 */
  7155.             padding: 2px 0 12px;
  7156.         }
  7157.         /* is-scroll(横スクロール)内では選択肢を折り返さず単一行に固定する。
  7158.            折り返すと行高が不揃いになり overflow-y:hidden で下枠が切れるため、
  7159.            長い選択肢は折り返さず横スクロールで見せる(本来の設計意図)。 */
  7160.         .rp-btn-group.is-scroll .rp-btn,
  7161.         .rp-btn-group.is-scroll .opt-btn,
  7162.         .opt-btn-group.is-scroll .rp-btn,
  7163.         .opt-btn-group.is-scroll .opt-btn {
  7164.             white-space: nowrap;
  7165.             word-break: normal;
  7166.             overflow-wrap: normal;
  7167.         }
  7168.         .rp-btn-group.is-scroll::-webkit-scrollbar,
  7169.         .opt-btn-group.is-scroll::-webkit-scrollbar {
  7170.             height: 6px;
  7171.         }
  7172.         .rp-btn-group.is-scroll::-webkit-scrollbar-thumb,
  7173.         .opt-btn-group.is-scroll::-webkit-scrollbar-thumb {
  7174.             background: #c0c0c0;
  7175.             border-radius: 3px;
  7176.         }
  7177.         /* ---- 3. プルダウン(画像なし・9個以上)---- */
  7178.         .rp-select-wrap {
  7179.             margin-bottom: 4px;
  7180.         }
  7181.         .rp-select {
  7182.             width: 100%;
  7183.             max-width: 420px;
  7184.             padding: 8px 12px;
  7185.             border: 2px solid #ddd;
  7186.             border-radius: 10px;
  7187.             font-size: 13px;
  7188.             color: #333;
  7189.             background: #fff;
  7190.             appearance: none;
  7191.             background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E\");
  7192.             background-repeat: no-repeat;
  7193.             background-position: right 12px center;
  7194.             cursor: pointer;
  7195.         }
  7196.         .rp-select:focus {
  7197.             outline: none;
  7198.             border-color: #1a6fcf;
  7199.         }
  7200.         /* ---- オプション選択ボタン(枠線ラジオ)---- */
  7201.         .opt-btn-group {
  7202.             display: flex;
  7203.             flex-wrap: wrap;
  7204.             gap: 8px;
  7205.             padding: 6px 0;
  7206.             max-width: 100%;
  7207.             min-width: 0;
  7208.         }
  7209.         .opt-btn {
  7210.             cursor: pointer;
  7211.             touch-action: manipulation; /* drop iOS 300ms tap delay (#15) */
  7212.             -webkit-tap-highlight-color: rgba(0,0,0,0);
  7213.             padding: 7px 14px;
  7214.             border: 2px solid #ddd;
  7215.             border-radius: 10px;
  7216.             font-size: 13px;
  7217.             color: #333;
  7218.             background: #fff;
  7219.             transition: border-color 0.2s, background 0.2s;
  7220.             white-space: normal;
  7221.             max-width: 100%;
  7222.             overflow-wrap: anywhere;
  7223.             text-decoration: none;
  7224.         }
  7225.         @media (hover: hover) and (pointer: fine) {
  7226.             .opt-btn:hover { border-color: #999; }
  7227.         }
  7228.         .opt-btn.is-selected {
  7229.             border-color: #1a6fcf;
  7230.             color: #1a6fcf;
  7231.             font-weight: bold;
  7232.             background: #f0f6ff;
  7233.         }
  7234.         .opt-btn input[type=\"radio\"] {
  7235.             position: absolute; opacity: 0; width: 1px; height: 1px;
  7236.             margin: 0; pointer-events: none;
  7237.         }
  7238.         /* opt-btn with color swatch image. The label still works as a
  7239.            radio target — clicking the image checks the input. The text
  7240.            label stays under the image so users can still read the name. */
  7241.         .opt-btn--with-image {
  7242.             padding: 4px 6px 6px;
  7243.             white-space: normal;
  7244.             text-align: center;
  7245.             display: inline-flex;
  7246.             flex-direction: column;
  7247.             align-items: center;
  7248.             min-width: 96px;
  7249.             max-width: 140px;
  7250.         }
  7251.         .opt-btn--with-image .opt-btn__img {
  7252.             display: block;
  7253.             width: 88px;
  7254.             height: 66px;
  7255.             object-fit: cover;
  7256.             border-radius: 6px;
  7257.             margin-bottom: 4px;
  7258.             background: #f5f5f5;
  7259.         }
  7260.         .opt-btn--with-image .opt-btn__name {
  7261.             display: block;
  7262.             font-size: 11px;
  7263.             line-height: 1.3;
  7264.             color: inherit;
  7265.         }
  7266.         .opt-btn--with-image.is-selected .opt-btn__img {
  7267.             outline: 2px solid #1a6fcf;
  7268.             outline-offset: 1px;
  7269.         }
  7270.         /* sale_type=2 (内窓) 補助金対象ガラスの強調表示.
  7271.            補助金が出る性能区分 (真空断熱 / Low-E複層 等) のガラス選択肢に
  7272.            緑枠 + 「補助金対象」バッジを付け、選択前から判別できるようにする。 */
  7273.         .opt-btn--subsidy {
  7274.             border-color: #2e7d32;
  7275.         }
  7276.         .opt-btn--subsidy.is-selected {
  7277.             border-color: #1a6fcf;
  7278.         }
  7279.         .opt-btn__subsidy-badge {
  7280.             display: inline-block;
  7281.             margin-left: 6px;
  7282.             padding: 1px 6px;
  7283.             border-radius: 6px;
  7284.             background: #2e7d32;
  7285.             color: #fff;
  7286.             font-size: 11px;
  7287.             font-weight: bold;
  7288.             white-space: nowrap;
  7289.         }
  7290.         /* ============================================
  7291.            施工エリア案内
  7292.         ============================================ */
  7293.         .ec-areaNotice {
  7294.             margin: 16px 0;
  7295.             padding: 16px 20px;
  7296.             background: #f8f9fa;
  7297.             border-left: 4px solid #1a6fcf;
  7298.             border-radius: 0 8px 8px 0;
  7299.         }
  7300.         .ec-areaNotice__inner {
  7301.             display: flex;
  7302.             align-items: flex-start;
  7303.             gap: 12px;
  7304.         }
  7305.         .ec-areaNotice__icon {
  7306.             font-size: 22px;
  7307.             line-height: 1;
  7308.             flex-shrink: 0;
  7309.             margin-top: 2px;
  7310.         }
  7311.         .ec-areaNotice__body {
  7312.             flex: 1;
  7313.         }
  7314.         .ec-areaNotice__title {
  7315.             font-size: 13px;
  7316.             font-weight: bold;
  7317.             color: #1a6fcf;
  7318.             margin: 0 0 6px;
  7319.         }
  7320.         .ec-areaNotice__text {
  7321.             font-size: 13px;
  7322.             color: #444;
  7323.             line-height: 1.7;
  7324.             margin: 0;
  7325.         }
  7326.         .ec-areaNotice__text strong {
  7327.             color: #222;
  7328.         }
  7329.         .ec-areaNotice__link {
  7330.             display: inline-block;
  7331.             margin-top: 8px;
  7332.             font-size: 12px;
  7333.             color: #1a6fcf;
  7334.             text-decoration: underline;
  7335.         }
  7336.         .ec-areaNotice__link:hover {
  7337.             color: #0d4fa0;
  7338.         }
  7339.         /* ============================================
  7340.            SNSシェア + ブランド名 タイトル行
  7341.         ============================================ */
  7342.         .ec-productRole__titleRow {
  7343.             display: flex;
  7344.             align-items: center;
  7345.             justify-content: space-between;
  7346.             gap: 8px;
  7347.             margin-bottom: 4px;
  7348.         }
  7349.         .ec-productRole__titleRow .ec-headingTitle {
  7350.             margin: 0;
  7351.             flex: 1;
  7352.             font-size: 18px;
  7353.         }
  7354.         .ec-share-inline {
  7355.             display: flex;
  7356.             align-items: center;
  7357.             gap: 8px;
  7358.             flex-shrink: 0;
  7359.         }
  7360.         @media (max-width: 767px) {
  7361.             /* maker_area の float を解除して独立表示 */
  7362.             #maker_area {
  7363.                 float: none !important;
  7364.                 width: auto !important;
  7365.                 height: auto !important;
  7366.                 display: block;
  7367.                 margin-bottom: 4px;
  7368.             }
  7369.             /* タイトル行: 商品名が全幅を占有しSNSは右寄せ下段 */
  7370.             .ec-productRole__titleRow {
  7371.                 flex-wrap: wrap;
  7372.                 clear: both;
  7373.             }
  7374.             .ec-productRole__titleRow .ec-headingTitle {
  7375.                 flex: 1 1 100%;
  7376.                 font-size: 16px;
  7377.             }
  7378.             .ec-share-inline {
  7379.                 flex: 0 0 auto;
  7380.                 margin-left: auto;
  7381.             }
  7382.         }
  7383.         .ec-share-inline a {
  7384.             display: flex;
  7385.             align-items: center;
  7386.             justify-content: center;
  7387.             width: 32px;
  7388.             height: 32px;
  7389.             border-radius: 50%;
  7390.             font-size: 15px;
  7391.             color: #fff;
  7392.             text-decoration: none;
  7393.             transition: opacity 0.2s;
  7394.         }
  7395.         .ec-share-inline a:hover { opacity: 0.8; }
  7396.         .ec-share-inline .share-twitter  { background: #000; }
  7397.         .ec-share-inline .share-facebook { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); }
  7398.         .ec-share-inline .share-line     { background: #06c755; }
  7399.         /* description_detail下のシェアブロックはPC/スマホ共通で非表示(タイトル行に移動) */
  7400.         .ec-productRole__share { display: none; }
  7401.         /* ============================================
  7402.            PC用: 現在のお見積り額カード強調
  7403.         ============================================ */
  7404.         @media (min-width: 768px) {
  7405.             .mitsumori-card-pc {
  7406.                 border: 2px solid #1a6fcf !important;
  7407.                 border-radius: 10px !important;
  7408.                 box-shadow: 0 4px 16px rgba(26,111,207,0.18) !important;
  7409.                 margin-top: 20px;
  7410.                 overflow: hidden;
  7411.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  7412.             }
  7413.             .mitsumori-card-pc .card-header {
  7414.                 background: linear-gradient(135deg, #1a6fcf, #0d4fa0) !important;
  7415.                 color: #fff !important;
  7416.                 padding: 14px 16px !important;
  7417.                 border-bottom: none !important;
  7418.             }
  7419.             .mitsumori-card-pc .card-title {
  7420.                 color: #fff !important;
  7421.                 font-size: 15px !important;
  7422.                 font-weight: bold !important;
  7423.                 margin: 0 !important;
  7424.             }
  7425.             .mitsumori-card-pc #mitsumori_message {
  7426.                 font-size: 22px !important;
  7427.                 font-weight: bold !important;
  7428.                 color: #fff !important;
  7429.             }
  7430.             .mitsumori-card-pc .btn-tool {
  7431.                 color: #fff !important;
  7432.             }
  7433.             /* 合計行を大きく強調 */
  7434.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  7435.                 font-size: 16px !important;
  7436.                 font-weight: bold !important;
  7437.                 color: #c00 !important;
  7438.                 background: #fff8f8 !important;
  7439.                 padding: 12px 16px !important;
  7440.             }
  7441.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  7442.                 font-size: 20px !important;
  7443.                 font-weight: bold !important;
  7444.                 color: #c00 !important;
  7445.             }
  7446.             /* card-body(明細リスト)を白背景に */
  7447.             .mitsumori-card-pc .card-body {
  7448.                 background: #fff !important;
  7449.             }
  7450.             .mitsumori-card-pc .card-footer {
  7451.                 background: #f8faff !important;
  7452.                 border-top: 1px solid #dce8fb !important;
  7453.                 padding: 12px 16px !important;
  7454.             }
  7455.         }
  7456.         @media (max-width: 767px) {
  7457.             /* スマホでは現在のお見積り額カードの強調スタイルをすべてリセット */
  7458.             .mitsumori-card-pc {
  7459.                 border: none !important;
  7460.                 border-radius: 0 !important;
  7461.                 box-shadow: none !important;
  7462.                 margin-top: 0 !important;
  7463.                 overflow: visible !important;
  7464.                 background: none !important;
  7465.                 /* sticky-top(position:sticky / z-index:1020) を解除。
  7466.                    そのままだと最下部で #sp-mitsumori-bar(z-index:1000) の上に
  7467.                    重なり、合計バーと文字が被るため通常フローへ戻す。 */
  7468.                 position: static !important;
  7469.                 z-index: auto !important;
  7470.             }
  7471.             .mitsumori-card-pc .card-header {
  7472.                 background: none !important;
  7473.                 color: inherit !important;
  7474.                 padding: inherit !important;
  7475.                 border-bottom: inherit !important;
  7476.             }
  7477.             .mitsumori-card-pc .card-title { color: inherit !important; }
  7478.             .mitsumori-card-pc #mitsumori_message { font-size: inherit !important; color: inherit !important; }
  7479.             .mitsumori-card-pc .btn-tool { color: inherit !important; }
  7480.             /* 折りたたみトグルボタン */
  7481.             .btn-mitsumori-toggle {
  7482.                 background: none !important;
  7483.                 border: 1px solid #aaa !important;
  7484.                 border-radius: 4px !important;
  7485.                 padding: 2px 8px !important;
  7486.                 font-size: 12px !important;
  7487.                 color: #333 !important;
  7488.                 line-height: 1.4 !important;
  7489.             }
  7490.             .btn-mitsumori-toggle .toggle-icon {
  7491.                 display: inline-block;
  7492.                 transition: transform 0.2s;
  7493.             }
  7494.             /* 展開状態: ▼→▲ */
  7495.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon::before {
  7496.                 content: \"▲ 閉じる\";
  7497.             }
  7498.             .card:not(.collapsed-card) .btn-mitsumori-toggle .toggle-icon {
  7499.                 display: none;
  7500.             }
  7501.             .card:not(.collapsed-card) .btn-mitsumori-toggle::after {
  7502.                 content: \"▲ 閉じる\";
  7503.                 font-size: 12px;
  7504.             }
  7505.             .mitsumori-card-pc .nav-item:first-child .nav-link {
  7506.                 font-size: inherit !important;
  7507.                 color: inherit !important;
  7508.                 background: none !important;
  7509.                 padding: inherit !important;
  7510.             }
  7511.             .mitsumori-card-pc .nav-item:first-child #mitsumori_goukei {
  7512.                 font-size: inherit !important;
  7513.                 color: inherit !important;
  7514.             }
  7515.             .mitsumori-card-pc .card-footer {
  7516.                 background: none !important;
  7517.                 border-top: inherit !important;
  7518.                 padding: inherit !important;
  7519.             }
  7520.             /* 横スクロール禁止 */
  7521.             body, html {
  7522.                 overflow-x: hidden;
  7523.                 max-width: 100vw;
  7524.             }
  7525.             /* ボタンの折り返しを許可(nowrapが原因で横スクロール発生するため) */
  7526.             .opt-btn,
  7527.             .rp-btn {
  7528.                 white-space: normal;
  7529.                 word-break: break-all;
  7530.             }
  7531.             /* エリア案内: スマホでコンパクト */
  7532.             .ec-areaNotice {
  7533.                 margin: 8px 0;
  7534.                 padding: 8px 10px;
  7535.                 border-left-width: 3px;
  7536.                 cursor: pointer;
  7537.             }
  7538.             .ec-areaNotice__inner {
  7539.                 flex-direction: row;
  7540.                 gap: 8px;
  7541.                 align-items: flex-start;
  7542.             }
  7543.             .ec-areaNotice__icon { font-size: 15px; }
  7544.             /* タイトル行: 展開トグル */
  7545.             .ec-areaNotice__title {
  7546.                 font-size: 11px;
  7547.                 margin-bottom: 3px;
  7548.                 display: flex;
  7549.                 justify-content: space-between;
  7550.                 align-items: center;
  7551.             }
  7552.             .ec-areaNotice__title::after {
  7553.                 content: \"▼\";
  7554.                 font-size: 9px;
  7555.                 color: #888;
  7556.                 margin-left: 6px;
  7557.                 transition: transform 0.2s;
  7558.             }
  7559.             .ec-areaNotice.is-open .ec-areaNotice__title::after {
  7560.                 transform: rotate(180deg);
  7561.             }
  7562.             /* 折りたたみ対象: 閉じた状態では非表示 */
  7563.             .ec-areaNotice__detail {
  7564.                 display: none;
  7565.             }
  7566.             .ec-areaNotice.is-open .ec-areaNotice__detail {
  7567.                 display: block;
  7568.             }
  7569.             .ec-areaNotice__text { font-size: 11px; line-height: 1.5; }
  7570.             .ec-areaNotice__text br { display: none; }
  7571.             .ec-areaNotice__link { font-size: 11px; margin-top: 3px; }
  7572.             .rp-card { width: calc(33.333% - 6px); min-width: 80px; }
  7573.             
  7574.             #sp-mitsumori-bar {
  7575.                 display: flex;
  7576.                 position: fixed;
  7577.                 bottom: 0;
  7578.                 left: 0;
  7579.                 right: 0;
  7580.                 z-index: 1000;
  7581.                 background: #fff;
  7582.                 border-top: 2px solid #e0e0e0;
  7583.                 box-shadow: 0 -2px 8px rgba(0,0,0,0.12);
  7584.                 align-items: center;
  7585.                 padding: 8px 10px calc(8px + env(safe-area-inset-bottom)) 10px;
  7586.                 gap: 8px;
  7587.             }
  7588.             #sp-mitsumori-bar .sp-bar__label {
  7589.                 font-size: 11px;
  7590.                 color: #666;
  7591.                 white-space: nowrap;
  7592.             }
  7593.             /* 価格ラッパ: 合計金額は最重要のため常に全桁表示する(縮小・省略しない)。
  7594.                幅が足りない場合は下のボタン側を縮める(flex 配分でボタンが先に縮む)。 */
  7595.             #sp-mitsumori-bar .sp-bar__pricewrap {
  7596.                 flex: 0 0 auto;
  7597.                 min-width: 0;
  7598.             }
  7599.             #sp-mitsumori-bar .sp-bar__price {
  7600.                 font-size: 18px;
  7601.                 font-weight: bold;
  7602.                 color: #c00;
  7603.                 white-space: nowrap;
  7604.             }
  7605.             #sp-mitsumori-bar .sp-bar__btn {
  7606.                 font-size: 12px;
  7607.                 padding: 8px 12px;
  7608.                 background: #333;
  7609.                 color: #fff;
  7610.                 border: none;
  7611.                 border-radius: 6px;
  7612.                 white-space: nowrap;
  7613.                 cursor: pointer;
  7614.                 position: relative;
  7615.                 display: inline-flex;
  7616.                 align-items: center;
  7617.                 gap: 6px;
  7618.                 flex: 1 1 auto;
  7619.                 min-width: 0;
  7620.                 justify-content: center;
  7621.             }
  7622.             #sp-mitsumori-bar .sp-bar__btn i {
  7623.                 font-size: 14px;
  7624.                 flex: 0 0 auto;
  7625.             }
  7626.             /* 幅が足りないときはボタンの文字を省略し、価格と数字を守る。 */
  7627.             #sp-mitsumori-bar .sp-bar__btn-label {
  7628.                 overflow: hidden;
  7629.                 text-overflow: ellipsis;
  7630.                 white-space: nowrap;
  7631.             }
  7632.             #sp-mitsumori-bar .sp-bar__cart-badge {
  7633.                 position: absolute;
  7634.                 top: -6px;
  7635.                 right: -6px;
  7636.                 background: #c00;
  7637.                 color: #fff;
  7638.                 border-radius: 50%;
  7639.                 min-width: 16px;
  7640.                 height: 16px;
  7641.                 font-size: 10px;
  7642.                 line-height: 16px;
  7643.                 padding: 0 4px;
  7644.                 font-weight: bold;
  7645.             }
  7646.             #sp-mitsumori-bar .sp-bar__home-btn {
  7647.                 display: inline-flex;
  7648.                 align-items: center;
  7649.                 justify-content: center;
  7650.                 width: 36px;
  7651.                 height: 36px;
  7652.                 flex: 0 0 auto;
  7653.                 border: 1px solid #ccc;
  7654.                 border-radius: 6px;
  7655.                 background: #fff;
  7656.                 color: #333;
  7657.                 text-decoration: none;
  7658.                 cursor: pointer;
  7659.             }
  7660.             #sp-mitsumori-bar .sp-bar__home-btn i {
  7661.                 font-size: 16px;
  7662.             }
  7663.             #sp-mitsumori-bar .sp-bar__home-btn:hover {
  7664.                 background: #f0f0f0;
  7665.             }
  7666.             /* 下部バーの高さ分ページ下部にpaddingを追加 (iOS safe-area 込み) */
  7667.             body {
  7668.                 padding-bottom: calc(80px + env(safe-area-inset-bottom));
  7669.             }
  7670.         }
  7671.         /* ============================================
  7672.            カート追加モーダル: 縦並び中央配置
  7673.         ============================================ */
  7674.         .add-cart-modal__wrap {
  7675.             text-align: center;
  7676.         }
  7677.         .add-cart-modal__header {
  7678.             font-size: 16px;
  7679.             margin: 20px 0 24px;
  7680.             text-align: center;
  7681.         }
  7682.         .add-cart-modal__actions {
  7683.             display: flex;
  7684.             flex-direction: column;
  7685.             align-items: center;
  7686.             gap: 16px;
  7687.             padding: 0 20px 20px;
  7688.         }
  7689.         .add-cart-modal__primary {
  7690.             display: inline-block;
  7691.             width: 80%;
  7692.             max-width: 320px;
  7693.             padding: 14px 20px;
  7694.             font-size: 15px;
  7695.             font-weight: bold;
  7696.             text-align: center;
  7697.             background: #d9534f;
  7698.             color: #fff !important;
  7699.             border-radius: 6px;
  7700.             text-decoration: none;
  7701.             cursor: pointer;
  7702.         }
  7703.         .add-cart-modal__primary:hover {
  7704.             background: #c9302c;
  7705.             color: #fff !important;
  7706.             text-decoration: none;
  7707.         }
  7708.         .add-cart-modal__secondary {
  7709.             display: inline-block;
  7710.             padding: 6px 14px;
  7711.             font-size: 12px;
  7712.             color: #666;
  7713.             border: 1px solid #ccc;
  7714.             border-radius: 4px;
  7715.             background: #fff;
  7716.             cursor: pointer;
  7717.         }
  7718.         .add-cart-modal__secondary:hover {
  7719.             background: #f0f0f0;
  7720.             color: #333;
  7721.         }
  7722.         @media (max-width: 767px) {
  7723.             .add-cart-modal__actions {
  7724.                 gap: 20px;
  7725.             }
  7726.         }
  7727.     </style>
  7728. {% endblock %}
  7729. {% block javascript %}
  7730.     <script>
  7731.         eccube.classCategories = {{ class_categories_as_json(Product)|raw }};
  7732.         // 規格2に選択肢を割り当てる。
  7733.         function fnSetClassCategories(form, classcat_id2_selected) {
  7734.             var \$form = \$(form);
  7735.             var product_id = \$form.find('input[name=product_id]').val();
  7736.             var \$sele1 = \$form.find('select[name=classcategory_id1]');
  7737.             var \$sele2 = \$form.find('select[name=classcategory_id2]');
  7738.             eccube.setClassCategories(\$form, product_id, \$sele1, \$sele2, classcat_id2_selected);
  7739.         }
  7740.         {% if form.classcategory_id2 is defined %}
  7741.         fnSetClassCategories(
  7742.             \$('#form1'), {{ form.classcategory_id2.vars.value|json_encode|raw }}
  7743.         );
  7744.         {% elseif form.classcategory_id1 is defined %}
  7745.         eccube.checkStock(\$('#form1'), {{ Product.id }}, {{ form.classcategory_id1.vars.value|json_encode|raw }}, null);
  7746.         {% endif %}
  7747.     </script>
  7748.     <script>
  7749.         \$(function() {
  7750.             // bfcache無効化
  7751.             \$(window).bind('pageshow', function(event) {
  7752.                 if (event.originalEvent.persisted) {
  7753.                     location.reload(true);
  7754.                 }
  7755.             });
  7756.             // Core Web Vital の Cumulative Layout Shift(CLS)対策のため
  7757.             // img タグに width, height が付与されている.
  7758.             // 630px 未満の画面サイズでは縦横比が壊れるための対策
  7759.             // see https://github.com/EC-CUBE/ec-cube/pull/5023
  7760.             \$('.ec-grid2__cell').hide();
  7761.             var removeSize = function () {
  7762.                 \$('.slide-item').height('');
  7763.                 \$('.slide-item img')
  7764.                     .removeAttr('width')
  7765.                     .removeAttr('height')
  7766.                     .removeAttr('style');
  7767.             };
  7768.             var slickInitial = function(slick) {
  7769.                 \$('.ec-grid2__cell').fadeIn(1500);
  7770.                 var baseHeight = \$(slick.target).height();
  7771.                 var baseWidth = \$(slick.target).width();
  7772.                 var rate = baseWidth / baseHeight;
  7773. \t\t\t\tif(baseHeight * rate < 400){
  7774. \t                \$('.slide-item').height(baseHeight * rate); // 余白を削除する
  7775. \t\t\t\t}else{
  7776. \t                \$('.slide-item').height(400); // 余白を削除する
  7777. \t\t\t\t}
  7778.                 // transform を使用することでCLSの影響を受けないようにする
  7779.                 \$('.slide-item img')
  7780.                     .css(
  7781.                         {
  7782.                             'transform-origin': 'top left',
  7783.                             'transform': 'scaleY(' + rate + ')',
  7784.                             'transition': 'transform .1s'
  7785.                         }
  7786.                     );
  7787.                 // 正しいサイズに近くなったら属性を解除する
  7788.                 setTimeout(removeSize, 500);
  7789.             };
  7790.             \$('.item_visual').on('init', slickInitial);
  7791.             // リサイズ時は CLS の影響を受けないため属性を解除する
  7792.             \$(window).resize(removeSize);
  7793.             \$('.item_visual').slick({
  7794.                 dots: false,
  7795.                 arrows: true,
  7796.                 responsive: [{
  7797.                     breakpoint: 768,
  7798.                     settings: {
  7799.                         dots: true,
  7800.                 \t\tarrows: false
  7801.                     }
  7802.                 }]
  7803.             });
  7804.             \$('.slideThumb').on('click', function() {
  7805.                 var index = \$(this).attr('data-index');
  7806.                 \$('.item_visual').slick('slickGoTo', index, false);
  7807.             })
  7808.         });
  7809.     </script>
  7810.     <script>
  7811.         \$(function() {
  7812.             \$('.add-cart').on('click', function(event) {
  7813.                 {% if form.classcategory_id1 is defined %}
  7814.                 // 規格1フォームの必須チェック
  7815.                 if (\$('#classcategory_id1').val() == '__unselected' || \$('#classcategory_id1').val() == '') {
  7816.                     \$('#classcategory_id1')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  7817.                     return true;
  7818.                 } else {
  7819.                     \$('#classcategory_id1')[0].setCustomValidity('');
  7820.                 }
  7821.                 {% endif %}
  7822.                 {% if form.classcategory_id2 is defined %}
  7823.                 // 規格2フォームの必須チェック
  7824.                 if (\$('#classcategory_id2').val() == '__unselected' || \$('#classcategory_id2').val() == '') {
  7825.                     \$('#classcategory_id2')[0].setCustomValidity('{{ '項目が選択されていません'|trans }}');
  7826.                     return true;
  7827.                 } else {
  7828.                     \$('#classcategory_id2')[0].setCustomValidity('');
  7829.                 }
  7830.                 {% endif %}
  7831.                 // タイプ2: カート送信直前に set_count を quantity に同期
  7832.                 if(\$('#set_count').length){
  7833.                     var _sc = parseInt(\$('#set_count').val()) || 1;
  7834.                     \$('#quantity').val(_sc);
  7835.                     \$('input[name=\"quantity\"]').val(_sc);
  7836.                 }
  7837.                 // 個数フォームのチェック
  7838.                 if (\$('#quantity').val() < 1) {
  7839.                     \$('#quantity')[0].setCustomValidity('{{ '1以上で入力してください。'|trans }}');
  7840.                     return true;
  7841.                 } else {
  7842.                     \$('#quantity')[0].setCustomValidity('');
  7843.                 }
  7844.                 event.preventDefault();
  7845.                 \$form = \$('#form1');
  7846.                 \$.ajax({
  7847.                     url: \$form.attr('action'),
  7848.                     type: \$form.attr('method'),
  7849.                     data: \$form.serialize(),
  7850.                     dataType: 'json',
  7851.                     beforeSend: function(xhr, settings) {
  7852.                         // Buttonを無効にする
  7853.                         \$('.add-cart').prop('disabled', true);
  7854.                     }
  7855.                 }).done(function(data) {
  7856.                     // レスポンス内のメッセージをalertで表示
  7857.                     \$.each(data.messages, function() {
  7858.                         \$('#ec-modal-header').text(this);
  7859.                     });
  7860.                     \$('.ec-modal').show()
  7861.                     // カートブロックを更新する
  7862.                     \$.ajax({
  7863.                         url: \"{{ url('block_cart') }}\",
  7864.                         type: 'GET',
  7865.                         dataType: 'html'
  7866.                     }).done(function(html) {
  7867.                         \$('.ec-headerRole__cart').html(html);
  7868.                     });
  7869.                 }).fail(function(data) {
  7870.                     alert('{{ 'カートへの追加に失敗しました。'|trans }}');
  7871.                 }).always(function(data) {
  7872.                     // Buttonを有効にする
  7873.                     \$('.add-cart').prop('disabled', false);
  7874.                 });
  7875.             });
  7876.         });
  7877.         \$('.ec-modal-wrap').on('click', function(e) {
  7878.             // モーダル内の処理は外側にバブリングさせない
  7879.             e.stopPropagation();
  7880.         });
  7881.         \$('.ec-modal-overlay, .ec-modal, .ec-modal-close, .ec-inlineBtn--cancel').on('click', function() {
  7882.             \$('.ec-modal').hide()
  7883.         });
  7884. \t\tvar pw = \"{% if mitsumori_json %}{{ mitsumori_json.pw }}{% endif %}\";
  7885. \t\tvar pd = \"{% if mitsumori_json %}{{ mitsumori_json.pd }}{% endif %}\";
  7886. \t\tvar ph = \"{% if mitsumori_json %}{{ mitsumori_json.ph }}{% endif %}\";
  7887. \t\tvar pm = \"{% if mitsumori_json %}{{ mitsumori_json.pm }}{% endif %}\";
  7888. \t\tvar pc = \"{% if mitsumori_json %}{{ mitsumori_json.pc }}{% endif %}\";
  7889. \t\t// option1 / option2: カテゴリ別 option 軸 (um: タイプ=subtype, fe: ct_up 等)
  7890. \t\tvar option1 = \"{% if mitsumori_json and mitsumori_json.option1 is defined %}{{ mitsumori_json.option1 }}{% endif %}\";
  7891. \t\tvar option2 = \"{% if mitsumori_json and mitsumori_json.option2 is defined %}{{ mitsumori_json.option2 }}{% endif %}\";
  7892. \t\tvar op0 = \"{% if mitsumori_json %}{{ mitsumori_json.op[0] }}{% endif %}\";
  7893. \t\tvar op1 = \"{% if mitsumori_json %}{{ mitsumori_json.op[1] }}{% endif %}\";
  7894. \t\tvar op2 = \"{% if mitsumori_json %}{{ mitsumori_json.op[2] }}{% endif %}\";
  7895. \t\tvar op3 = \"{% if mitsumori_json %}{{ mitsumori_json.op[3] }}{% endif %}\";
  7896. \t\tvar op4 = \"{% if mitsumori_json %}{{ mitsumori_json.op[4] }}{% endif %}\";
  7897. \t\tvar op5 = \"{% if mitsumori_json %}{{ mitsumori_json.op[5] }}{% endif %}\";
  7898. \t\tvar op6 = \"{% if mitsumori_json %}{{ mitsumori_json.op[6] }}{% endif %}\";
  7899. \t\tvar op7 = \"{% if mitsumori_json %}{{ mitsumori_json.op[7] }}{% endif %}\";
  7900. \t\tvar op8 = \"{% if mitsumori_json %}{{ mitsumori_json.op[8] }}{% endif %}\";
  7901. \t\tvar op9 = \"{% if mitsumori_json %}{{ mitsumori_json.op[9] }}{% endif %}\";
  7902. \t\tvar op10 = \"{% if mitsumori_json %}{{ mitsumori_json.op[10] }}{% endif %}\";
  7903. \t\tconst formatter = new Intl.NumberFormat('ja-JP');
  7904. \t\t// ============================================================
  7905. \t\t//  free_area 1 エントリのスキーマ(11 キー固定)
  7906. \t\t// ============================================================
  7907. \t\t//   w           : 幅 (string, 例 \"239.9cm\" / tf は \"1m\")
  7908. \t\t//   d           : 奥行
  7909. \t\t//   h           : 高さ (tf はロール長 \"10m\")
  7910. \t\t//   m           : 素材
  7911. \t\t//   c           : カラー
  7912. \t\t//   price       : 販売価格 (税抜、amount=1 ベース)
  7913. \t\t//   unit_price  : 商品 per-unit 増分 (税抜、AMOUNT_CATEGORIES のみ)
  7914. \t\t//   maker_price : メーカー価格 (税抜)
  7915. \t\t//   ct          : 基本工事費 (税抜、amount=1 ベース)
  7916. \t\t//   option1     : fe → ct_up / その他カテゴリ → category-specific
  7917. \t\t//   option2     : um → ct_up / その他カテゴリ → category-specific
  7918. \t\t//
  7919. \t\t//  ct4 (設置場所) / ct5 (撤去) / ct6 (残土) は option_area 側で扱う.
  7920. \t\t// ============================================================
  7921. \t\t// 施工オプション定義(option_area)— 各エントリ {name, comment, on, off, price}
  7922. \t\tvar op_data = {{ op_json|default('[]')|raw }};
  7923. \t\t// option_item_area:
  7924. \t\t//   tg 用 — block 別オプション差額表
  7925. \t\t//     { axis_labels: {F:'床材',front:'前面型',side1:'右側面型',side2:'左側面型'},
  7926. \t\t//       blocks: { 'W_label|D_label': { F:[{idx,label,diff},...], front:[...], side1:[...], side2:[...] }, ... } }
  7927. \t\t//   fe (sale_type=4) 用 — ブロックの種類×段数の差額表 (fe_block キー)
  7928. \t\t//     { fe_block: { depends_on_name: '...', depends_on_value: '...',
  7929. \t\t//                   title: '...', default_key: '...',
  7930. \t\t//                   choices: [{key,label,price}, ...] } }
  7931. \t\t// 該当しないカテゴリでは fe_block は null. axis_labels/blocks は空.
  7932. \t\tvar oi_data = {{ oi_json|default('{\"axis_labels\":{},\"blocks\":{},\"fe_block\":null}')|raw }};
  7933. \t\t// 選択中の tg オプション差額 (axis -> selected choice_idx). ラジオ click で更新される.
  7934. \t\tvar oi_selected = { F: 1, front: 1, side1: 1, side2: 1 };
  7935. \t\t// 選択中の fe ブロック種類×段数 (key 文字列). 既定は oi_data.fe_block.default_key.
  7936. \t\tvar fe_block_selected = (oi_data && oi_data.fe_block && oi_data.fe_block.default_key) || '';
  7937. \t\t// sale_type ID(mtb_sale_type の id。本サイトでの意味は次の通り):
  7938. \t\t//   1 通常 / 2 補助金窓 / 3 物置 / 4 フェンス / 5 デッキ / 6 芝生 / 9 商品のみ
  7939. \t\tvar SALE_TYPE_ID = {{ ProductClass.SaleType.id }};
  7940. \t\t{# option1 / option2 ラベルをカテゴリ別に決定 (sh=31, rd=43, mo=15) — 以降の UI / JS 両方で使用 #}
  7941. \t\t{% set option1_label = 'オプション1' %}
  7942. \t\t{% set option2_label = 'オプション2' %}
  7943. \t\t{% if Product.ProductCategories is not empty %}
  7944. \t\t\t{% for pcat in Product.ProductCategories %}
  7945. \t\t\t\t{% if pcat.category_id == 31 %}{% set option1_label = 'サイズプリセット' %}{% set option2_label = '駆動方式' %}{% endif %}
  7946. \t\t\t\t{% if pcat.category_id == 43 %}{% set option1_label = 'ランマ' %}{% set option2_label = 'タイプ' %}{% endif %}
  7947. \t\t\t\t{% if pcat.category_id == 15 %}{% set option1_label = '棚タイプ' %}{% endif %}
  7948. \t\t\t\t{% if pcat.category_id == 17 %}{% set option1_label = '窓タイプ' %}{% endif %}
  7949. \t\t\t{% endfor %}
  7950. \t\t{% endif %}
  7951. \t\t// 消費税率(pp.price/pp.ct/op_data.price は scraper が税抜で保存しているため、
  7952. \t\t// calcGoukei 出口で 1+TAX_RATE を掛けて税込 mitsumori_goukei にする)
  7953. \t\tvar TAX_RATE = 0.10;
  7954. \t\tfunction toIncTax(v) { return Math.round(v * (1 + TAX_RATE)); }
  7955. \t\t/**
  7956. \t\t * tg 用 block 別オプション差額の集計.
  7957. \t\t *   現選択 (W, D) から block key を作り、oi_data.blocks[blockKey] を取得.
  7958. \t\t *   各 axis (F/front/side1/side2) で oi_selected[axis] の choice の diff を合計.
  7959. \t\t * 戻り値: { total: 差額合計(税抜), items: [{name, label, diff}, ...] }
  7960. \t\t *   block が無い (tg 以外 / 該当 (W,D) が未取得) なら total=0.
  7961. \t\t */
  7962. \t\tfunction collectOptionItems(curW, curD) {
  7963. \t\t\tvar result = { total: 0, items: [] };
  7964. \t\t\tif (!oi_data || !oi_data.blocks) return result;
  7965. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  7966. \t\t\tvar block = oi_data.blocks[blockKey];
  7967. \t\t\tif (!block) return result;
  7968. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  7969. \t\t\tfor (var i = 0; i < axes.length; i++) {
  7970. \t\t\t\tvar axis = axes[i];
  7971. \t\t\t\tvar choices = block[axis];
  7972. \t\t\t\tif (!choices || !choices.length) continue;
  7973. \t\t\t\tvar idx = oi_selected[axis] || 1;
  7974. \t\t\t\tvar pick = null;
  7975. \t\t\t\tfor (var j = 0; j < choices.length; j++) {
  7976. \t\t\t\t\tif (parseInt(choices[j].idx) === parseInt(idx)) { pick = choices[j]; break; }
  7977. \t\t\t\t}
  7978. \t\t\t\tif (!pick) pick = choices[0];
  7979. \t\t\t\tvar diff = parseInt(pick.diff) || 0;
  7980. \t\t\t\tresult.total += diff;
  7981. \t\t\t\tresult.items.push({
  7982. \t\t\t\t\tname:  oi_data.axis_labels[axis] || axis,
  7983. \t\t\t\t\tlabel: pick.label,
  7984. \t\t\t\t\tdiff:  diff,
  7985. \t\t\t\t});
  7986. \t\t\t}
  7987. \t\t\treturn result;
  7988. \t\t}
  7989. \t\t/**
  7990. \t\t * tg ラジオ群を block 別に DOM へ描画する.
  7991. \t\t *   W/D が確定したら現 block の 4 軸 (F/front/side1/side2) ラジオを #tg-options 要素に出す.
  7992. \t\t *   block が空なら #tg-options を空にする.
  7993. \t\t */
  7994. \t\tfunction renderOptionItemRadios(curW, curD) {
  7995. \t\t\tvar \$box = \$('#tg-options');
  7996. \t\t\tif (!\$box.length) return;
  7997. \t\t\t\$box.empty();
  7998. \t\t\tif (!oi_data || !oi_data.blocks) return;
  7999. \t\t\tvar blockKey = (curW || '') + '|' + (curD || '');
  8000. \t\t\tvar block = oi_data.blocks[blockKey];
  8001. \t\t\tif (!block) return;
  8002. \t\t\tvar axes = ['F', 'front', 'side1', 'side2'];
  8003. \t\t\taxes.forEach(function(axis) {
  8004. \t\t\t\tvar choices = block[axis];
  8005. \t\t\t\tif (!choices || !choices.length) return;
  8006. \t\t\t\tvar axisLabel = (oi_data.axis_labels && oi_data.axis_labels[axis]) || axis;
  8007. \t\t\t\tvar \$section = \$('<div class=\"form-group tg-axis\"></div>');
  8008. \t\t\t\t\$section.append('<p class=\"rp-section-label\"><strong>' + axisLabel + '</strong>: <span class=\"tg-axis-selected\"></span></p>');
  8009. \t\t\t\tvar \$list = \$('<div class=\"tg-choice-list\"></div>');
  8010. \t\t\t\tchoices.forEach(function(ch, i) {
  8011. \t\t\t\t\tvar inputId = 'tg_' + axis + '_' + ch.idx;
  8012. \t\t\t\t\tvar name = 'tg_' + axis;
  8013. \t\t\t\t\tvar checked = (parseInt(ch.idx) === parseInt(oi_selected[axis] || 1)) ? ' checked' : '';
  8014. \t\t\t\t\tvar diffTxt = ch.diff > 0 ? '+' + formatter.format(ch.diff) + '円' : (ch.diff < 0 ? formatter.format(ch.diff) + '円' : '±0');
  8015. \t\t\t\t\t\$list.append(
  8016. \t\t\t\t\t\t'<label class=\"tg-choice\"><input type=\"radio\" name=\"' + name + '\" id=\"' + inputId + '\" value=\"' + ch.idx + '\" data-axis=\"' + axis + '\"' + checked + '> ' +
  8017. \t\t\t\t\t\tch.label + '<span class=\"tg-diff\">(' + diffTxt + ')</span></label>'
  8018. \t\t\t\t\t);
  8019. \t\t\t\t});
  8020. \t\t\t\t\$section.append(\$list);
  8021. \t\t\t\t\$box.append(\$section);
  8022. \t\t\t});
  8023. \t\t\t// ラジオ click で oi_selected を更新 → 再計算
  8024. \t\t\t\$box.off('change.tg').on('change.tg', 'input[type=\"radio\"][data-axis]', function() {
  8025. \t\t\t\tvar axis = \$(this).data('axis');
  8026. \t\t\t\toi_selected[axis] = parseInt(\$(this).val()) || 1;
  8027. \t\t\t\tmitsumori_simulation('refresh', '');
  8028. \t\t\t});
  8029. \t\t\tupdateOptionItemSelectedLabels();
  8030. \t\t}
  8031. \t\tfunction updateOptionItemSelectedLabels() {
  8032. \t\t\t\$('#tg-options .tg-axis').each(function() {
  8033. \t\t\t\tvar \$sel = \$(this).find('input[type=\"radio\"]:checked');
  8034. \t\t\t\tif (!\$sel.length) return;
  8035. \t\t\t\tvar label = \$sel.parent().contents().filter(function() { return this.nodeType === 3; }).text().trim();
  8036. \t\t\t\t\$(this).find('.tg-axis-selected').text(label);
  8037. \t\t\t});
  8038. \t\t}
  8039. \t\t// =========================================================
  8040. \t\t// fe (sale_type=4) ブロック種類×段数 サブ UI
  8041. \t\t// =========================================================
  8042. \t\t/**
  8043. \t\t * fe_block の親オプション (= op_data 内の「ご希望のフェンス設置方法」 entry)
  8044. \t\t * を name でルックアップし、その index を返す. 見つからなければ -1.
  8045. \t\t *   fe_block.depends_on_name が設定されていればそれで照合.
  8046. \t\t *   未設定なら 'ご希望のフェンス設置方法' を含む name にフォールバック.
  8047. \t\t */
  8048. \t\tfunction findFeBlockParentOpIndex() {
  8049. \t\t\tif (!oi_data || !oi_data.fe_block) return -1;
  8050. \t\t\tvar needle = oi_data.fe_block.depends_on_name || 'ご希望のフェンス設置方法';
  8051. \t\t\tfor (var i = 0; i < op_data.length; i++) {
  8052. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  8053. \t\t\t\tif (op_data[i].name.indexOf(needle) >= 0) return i;
  8054. \t\t\t}
  8055. \t\t\treturn -1;
  8056. \t\t}
  8057. \t\t/**
  8058. \t\t * fe_block の現在の選択値の price (税抜) と choice 内容を集計.
  8059. \t\t *   親オプション (= 'ご希望のフェンス設置方法') が depends_on_value を選んでいる
  8060. \t\t *   ときだけ加算する. それ以外 (既存ブロック側 / 親未選択) は price=0.
  8061. \t\t * 戻り値: { price: 0|N, choice: {key,label,price}|null, active: bool }
  8062. \t\t */
  8063. \t\tfunction collectFeBlock() {
  8064. \t\t\tvar result = { price: 0, choice: null, active: false };
  8065. \t\t\tif (SALE_TYPE_ID !== 4) return result;
  8066. \t\t\tif (!oi_data || !oi_data.fe_block) return result;
  8067. \t\t\tif (!oi_data.fe_block.choices || !oi_data.fe_block.choices.length) return result;
  8068. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8069. \t\t\tif (parentIdx < 0) return result;
  8070. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8071. \t\t\tvar parentSel = ops[parentIdx];
  8072. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  8073. \t\t\tif (parentSel !== triggerValue) return result;  // 親が新規ブロック積み以外なら無加算
  8074. \t\t\tresult.active = true;
  8075. \t\t\tvar choices = oi_data.fe_block.choices;
  8076. \t\t\tvar pick = null;
  8077. \t\t\tfor (var j = 0; j < choices.length; j++) {
  8078. \t\t\t\tif (choices[j].key === fe_block_selected) { pick = choices[j]; break; }
  8079. \t\t\t}
  8080. \t\t\tif (!pick) pick = choices[0];
  8081. \t\t\tresult.choice = pick;
  8082. \t\t\tresult.price  = parseInt(pick.price) || 0;
  8083. \t\t\treturn result;
  8084. \t\t}
  8085. \t\t/**
  8086. \t\t * fe_block ラジオ群を #fe-block-options 要素に描画する.
  8087. \t\t *   active=false (親が「新規にブロック積み」以外) のときは非表示.
  8088. \t\t */
  8089. \t\tfunction renderFeBlockRadios() {
  8090. \t\t\tvar \$box = \$('#fe-block-options');
  8091. \t\t\tif (!\$box.length) return;
  8092. \t\t\tif (!oi_data || !oi_data.fe_block || !oi_data.fe_block.choices) {
  8093. \t\t\t\t\$box.empty().hide();
  8094. \t\t\t\treturn;
  8095. \t\t\t}
  8096. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8097. \t\t\tif (parentIdx < 0) {
  8098. \t\t\t\t\$box.empty().hide();
  8099. \t\t\t\treturn;
  8100. \t\t\t}
  8101. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8102. \t\t\tvar triggerValue = oi_data.fe_block.depends_on_value || '新規にブロック積みを行う';
  8103. \t\t\tvar visible = (ops[parentIdx] === triggerValue);
  8104. \t\t\tif (!visible) {
  8105. \t\t\t\t\$box.hide();
  8106. \t\t\t\treturn;
  8107. \t\t\t}
  8108. \t\t\tvar fb = oi_data.fe_block;
  8109. \t\t\t\$box.empty();
  8110. \t\t\tvar \$title = \$('<p class=\"rp-section-label\"><strong>' + (fb.title || 'ブロックの種類と段数') + '</strong></p>');
  8111. \t\t\t\$box.append(\$title);
  8112. \t\t\t// 他オプション群と同じ .opt-btn-group / .opt-btn 形式で描画.
  8113. \t\t\t//   生の <label><input type=radio> ... 形式だと CSS 定義が無く
  8114. \t\t\t//   ラベル折り返し・縦ズレ・隣接 opt-btn との間隔不揃いが発生する.
  8115. \t\t\tvar \$list = \$('<div class=\"opt-btn-group\" style=\"flex-direction:column;align-items:stretch;\"></div>');
  8116. \t\t\tfb.choices.forEach(function(ch) {
  8117. \t\t\t\tvar inputId = 'fe_block_' + ch.key;
  8118. \t\t\t\tvar isSel   = (ch.key === fe_block_selected);
  8119. \t\t\t\tvar checked = isSel ? ' checked' : '';
  8120. \t\t\t\tvar selCls  = isSel ? ' is-selected' : '';
  8121. \t\t\t\tvar priceTxt = (parseInt(ch.price) || 0) > 0
  8122. \t\t\t\t\t? ' <span class=\"fe-block-price\" style=\"margin-left:6px;color:#666;font-size:12px;white-space:nowrap;\">(+' + formatter.format(toIncTax(parseInt(ch.price))) + '円 税込)</span>'
  8123. \t\t\t\t\t: '';
  8124. \t\t\t\t\$list.append(
  8125. \t\t\t\t\t'<label class=\"opt-btn' + selCls + '\" style=\"text-align:left;display:flex;align-items:center;flex-wrap:wrap;\">' +
  8126. \t\t\t\t\t'<input type=\"radio\" name=\"fe_block\" id=\"' + inputId + '\" value=\"' + ch.key + '\"' + checked + '>' +
  8127. \t\t\t\t\t'<span class=\"fe-block-label\">' + ch.label + '</span>' +
  8128. \t\t\t\t\tpriceTxt +
  8129. \t\t\t\t\t'</label>'
  8130. \t\t\t\t);
  8131. \t\t\t});
  8132. \t\t\t\$box.append(\$list);
  8133. \t\t\t\$box.show();
  8134. \t\t\t\$box.off('change.fe_block').on('change.fe_block', 'input[type=\"radio\"][name=\"fe_block\"]', function() {
  8135. \t\t\t\tfe_block_selected = \$(this).val();
  8136. \t\t\t\t// is-selected 切替 (opt-btn 形式共通)
  8137. \t\t\t\t\$box.find('label.opt-btn').removeClass('is-selected');
  8138. \t\t\t\t\$(this).closest('label.opt-btn').addClass('is-selected');
  8139. \t\t\t\tmitsumori_simulation('refresh', '');
  8140. \t\t\t});
  8141. \t\t}
  8142. \t\t/**
  8143. \t\t * fe (sale_type=4) で op_data エントリの連動表示制御.
  8144. \t\t *   親「ご希望のフェンス設置方法」の選択値に応じて、
  8145. \t\t *     - 「既存ブロックに穴空け工事が必要ですか?」 entry を表示/非表示
  8146. \t\t *   切替の trigger は親選択値の文字列で判定 (entry index にハードコードしない).
  8147. \t\t */
  8148. \t\tfunction updateFeOpConditionalVisibility() {
  8149. \t\t\tif (SALE_TYPE_ID !== 4) return;
  8150. \t\t\tvar parentIdx = findFeBlockParentOpIndex();
  8151. \t\t\tif (parentIdx < 0) return;
  8152. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8153. \t\t\tvar parentSel = ops[parentIdx];
  8154. \t\t\t// 親が「既存ブロックに設置する」 (= off 側) のとき穴空け entry を表示
  8155. \t\t\tvar triggerOffValue = (op_data[parentIdx] && op_data[parentIdx].off) || '既存ブロックに設置する';
  8156. \t\t\t\$('div[data-op-name]').each(function() {
  8157. \t\t\t\tvar n = \$(this).attr('data-op-name') || '';
  8158. \t\t\t\tif (n.indexOf('穴空け') >= 0) {
  8159. \t\t\t\t\tif (parentSel === triggerOffValue) {
  8160. \t\t\t\t\t\t\$(this).show();
  8161. \t\t\t\t\t} else {
  8162. \t\t\t\t\t\t\$(this).hide();
  8163. \t\t\t\t\t}
  8164. \t\t\t\t}
  8165. \t\t\t});
  8166. \t\t}
  8167. \t\t/**
  8168. \t\t * 選択中の施工オプションを集計し、ON選択分の price を合計する.
  8169. \t\t * 戻り値: { total: 合計金額, items: [{name, value, price}, ...] }
  8170. \t\t */
  8171. \t\tfunction collectOptions() {
  8172. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8173. \t\t\tvar total = 0;
  8174. \t\t\tvar items = [];
  8175. \t\t\tfor (var i = 0; i < ops.length; i++) {
  8176. \t\t\t\tif (!op_data[i] || !op_data[i].name) continue;
  8177. \t\t\t\tvar sel = ops[i];
  8178. \t\t\t\tif (!sel) continue;
  8179. \t\t\t\tvar price = parseInt(op_data[i].price) || 0;
  8180. \t\t\t\t// 「ON」選択時のみ加算(OFF や「不要」「商品購入のみ」は加算しない)
  8181. \t\t\t\tvar isOn = (sel === op_data[i].on);
  8182. \t\t\t\titems.push({
  8183. \t\t\t\t\tname:  op_data[i].name,
  8184. \t\t\t\t\tvalue: sel,
  8185. \t\t\t\t\tprice: isOn ? price : 0,
  8186. \t\t\t\t\ton:    op_data[i].on,
  8187. \t\t\t\t\toff:   op_data[i].off,
  8188. \t\t\t\t});
  8189. \t\t\t\tif (isOn) total += price;
  8190. \t\t\t}
  8191. \t\t\t// fe (sale_type=4) のブロック種類×段数 分を items / total に統合.
  8192. \t\t\t// 親オプション「ご希望のフェンス設置方法」 が 「新規にブロック積みを行う」 のとき
  8193. \t\t\t// だけ加算される (collectFeBlock 内で判定済み).
  8194. \t\t\tvar fb = collectFeBlock();
  8195. \t\t\tif (fb.active && fb.choice) {
  8196. \t\t\t\titems.push({
  8197. \t\t\t\t\tname:  (oi_data.fe_block && oi_data.fe_block.title) || 'ブロックの種類と段数',
  8198. \t\t\t\t\tvalue: fb.choice.label,
  8199. \t\t\t\t\tprice: fb.price,
  8200. \t\t\t\t\ton:    fb.choice.label,
  8201. \t\t\t\t\toff:   '',
  8202. \t\t\t\t});
  8203. \t\t\t\ttotal += fb.price;
  8204. \t\t\t}
  8205. \t\t\treturn { total: total, items: items };
  8206. \t\t}
  8207. \t\t/**
  8208. \t\t * free_area 1 エントリ ({w,d,h,m,c,price,unit_price,maker_price,ct,option1,option2})
  8209. \t\t * から sale_type 別に最終金額を算出する.
  8210. \t\t *
  8211. \t\t * 計算式(amount=1 ベース、出口で × 1.10 税込化):
  8212. \t\t *   1 通常        : price + ct + option_sum
  8213. \t\t *   2 補助金窓    : price × set_count + (ct + (set_count-1) × option2) + option_sum
  8214. \t\t *   3 物置        : (price + ct) × daisu + option_sum
  8215. \t\t *   4 フェンス    : price + (maisu-1) × unit_price
  8216. \t\t *                  + ct + max(0, maisu-3) × option1
  8217. \t\t *                  + option_sum   (maisu >= 3)
  8218. \t\t *   5 デッキ      : price + ct + option_sum   (area は表示用、計算非関与)
  8219. \t\t *   6 芝生        : price × ceil(area / (w_m × h_m)) + ct + option_sum
  8220. \t\t *   9 商品のみ    : price のみ(カート quantity 倍で総額)
  8221. \t\t *
  8222. \t\t * fe では option1 を ct_up、um では option2 を ct_up として転用.
  8223. \t\t * tf では w / h にロール幅・長さが格納されており parseLen で数値抽出.
  8224. \t\t *
  8225. \t\t * @param {Object} pp  free_area の 1 行(matrix エントリ)
  8226. \t\t * @param {number} optionTotal  collectOptions().total
  8227. \t\t * @param {Object} ctx  UI 入力 {set_count, daisu, maisu, area, quantityOnly, ...}
  8228. \t\t * @returns {Object} {goukei, price, ct, opt, qty}  すべて税込整数
  8229. \t\t */
  8230. \t\tfunction calcGoukei(pp, optionTotal, ctx) {
  8231. \t\t\tvar basePrice  = parseInt(pp.price)       || 0;
  8232. \t\t\tvar baseCt     = parseInt(pp.ct)          || 0;
  8233. \t\t\tvar unitPrice  = parseInt(pp.unit_price)  || 0;
  8234. \t\t\tvar optSum     = optionTotal;
  8235. \t\t\tvar price      = basePrice;
  8236. \t\t\tvar ct         = baseCt;
  8237. \t\t\tvar qty        = 1;
  8238. \t\t\tvar goukei     = 0;
  8239. \t\t\t// 「商品購入のみ」選択時は工事費・オプションをゼロにする(任意 sale_type で適用)
  8240. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8241. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  8242. \t\t\tif (purchaseOnly) {
  8243. \t\t\t\tbaseCt = 0;
  8244. \t\t\t\tct     = 0;
  8245. \t\t\t\toptSum = 0;
  8246. \t\t\t}
  8247. \t\t\tswitch (SALE_TYPE_ID) {
  8248. \t\t\t\tcase 2: {  // 補助金・窓 (シンプル表引き方式 2026-05-)
  8249. \t\t\t\t\t// 2026-05 仕様簡素化: 枚数軸を廃止し、subtype に枚数を内包.
  8250. \t\t\t\t\t// pp.price / pp.ct は (W, H, ガラス, subtype) の単一価格.
  8251. \t\t\t\t\t// 複数枚をまとめて買う場合はカート quantity で表現.
  8252. \t\t\t\t\tqty    = 1;
  8253. \t\t\t\t\tprice  = basePrice;
  8254. \t\t\t\t\tct     = baseCt;
  8255. \t\t\t\t\tgoukei = price + ct + optSum;
  8256. \t\t\t\t\tbreak;
  8257. \t\t\t\t}
  8258. \t\t\t\tcase 3: {  // 物置・ゴミステーション
  8259. \t\t\t\t\tqty   = Math.max(1, parseInt(ctx.daisu) || 1);
  8260. \t\t\t\t\tprice = basePrice * qty;
  8261. \t\t\t\t\tct    = baseCt * qty;
  8262. \t\t\t\t\tgoukei = price + ct + optSum;
  8263. \t\t\t\t\tbreak;
  8264. \t\t\t\t}
  8265. \t\t\t\tcase 4: {  // フェンス・組み立て式(maisu ≥ 3、base_amount = 3)
  8266. \t\t\t\t\t// scraper は amount=3 を base にしているので pp.price = price(3),
  8267. \t\t\t\t\t// pp.unit_price = price(4) - price(3).
  8268. \t\t\t\t\tqty   = Math.max(3, parseInt(ctx.maisu) || 3);
  8269. \t\t\t\t\tprice = basePrice + (qty - 3) * unitPrice;
  8270. \t\t\t\t\t// option1 が ct_up (4枚目以降の増分). 未設定なら ct 固定動作
  8271. \t\t\t\t\tvar ctUp1 = parseInt(pp.option1) || 0;
  8272. \t\t\t\t\tct = baseCt + Math.max(0, qty - 3) * ctUp1;
  8273. \t\t\t\t\t// fe_block(ブロック積み段数): collectOptions が base(3枚分)を optSum に
  8274. \t\t\t\t\t// 算入済み. ブロック費も本体同様に枚数連動するため、4枚目以降は 1枚毎に
  8275. \t\t\t\t\t// choice.unit_price(= block(4)-block(3)) を加算する.
  8276. \t\t\t\t\t// (顧客指摘「何枚施工でも増える金額が同じ」の是正。unit_price 未設定の
  8277. \t\t\t\t\t//  旧データでは +0 で従来動作。)
  8278. \t\t\t\t\tif (!purchaseOnly) {
  8279. \t\t\t\t\t\tvar fbC = collectFeBlock();
  8280. \t\t\t\t\t\tif (fbC.active && fbC.choice) {
  8281. \t\t\t\t\t\t\toptSum += Math.max(0, qty - 3) * (parseInt(fbC.choice.unit_price) || 0);
  8282. \t\t\t\t\t\t}
  8283. \t\t\t\t\t}
  8284. \t\t\t\t\tgoukei = price + ct + optSum;
  8285. \t\t\t\t\tbreak;
  8286. \t\t\t\t}
  8287. \t\t\t\tcase 5: {  // ウッドデッキ・タイルデッキ
  8288. \t\t\t\t\t// area は担当者向けの参考値として保持(計算には使わない)
  8289. \t\t\t\t\tqty    = 1;
  8290. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  8291. \t\t\t\t\tprice  = basePrice;
  8292. \t\t\t\t\tct     = baseCt;
  8293. \t\t\t\t\tbreak;
  8294. \t\t\t\t}
  8295. \t\t\t\tcase 6: {  // 芝生・人工芝(ロール単位)
  8296. \t\t\t\t\t// pp.w \"1m\", pp.h \"10m\" から数値抽出
  8297. \t\t\t\t\tvar w_m = parseLen(pp.w);
  8298. \t\t\t\t\tvar h_m = parseLen(pp.h);
  8299. \t\t\t\t\tvar rollSize = w_m * h_m;
  8300. \t\t\t\t\tif (!rollSize || rollSize <= 0) rollSize = 1;
  8301. \t\t\t\t\t// 施工サイズ(面積)があれば必要枚数を自動算出。無ければ直接指定の枚数を使う。
  8302. \t\t\t\t\tvar area  = parseFloat(ctx.area) || 0;
  8303. \t\t\t\t\tif (area > 0) {
  8304. \t\t\t\t\t\tqty = Math.max(1, Math.ceil(area / rollSize));
  8305. \t\t\t\t\t} else {
  8306. \t\t\t\t\t\tqty = Math.max(1, parseInt(ctx.tf_qty) || 1);
  8307. \t\t\t\t\t}
  8308. \t\t\t\t\tprice  = basePrice * qty;
  8309. \t\t\t\t\tct     = baseCt;
  8310. \t\t\t\t\tgoukei = price + ct + optSum;
  8311. \t\t\t\t\tbreak;
  8312. \t\t\t\t}
  8313. \t\t\t\tcase 7: {  // 数量買い・基本工事費固定(gf ガーデンファニチャー / st 石材)
  8314. \t\t\t\t\tqty    = Math.max(1, parseInt(ctx.suuryou) || 1);
  8315. \t\t\t\t\tprice  = basePrice * qty;
  8316. \t\t\t\t\tct     = baseCt;                 // ct は固定(数量に依らない)
  8317. \t\t\t\t\tgoukei = price + ct + optSum;
  8318. \t\t\t\t\tbreak;
  8319. \t\t\t\t}
  8320. \t\t\t\tcase 9: {  // 商品のみ購入
  8321. \t\t\t\t\t// カート側で quantity × unit price するため goukei は単品価格
  8322. \t\t\t\t\tqty    = parseInt(ctx.quantityOnly) || 1;
  8323. \t\t\t\t\tprice  = basePrice;
  8324. \t\t\t\t\tct     = 0;
  8325. \t\t\t\t\toptSum = 0;
  8326. \t\t\t\t\tgoukei = price;
  8327. \t\t\t\t\tbreak;
  8328. \t\t\t\t}
  8329. \t\t\t\tdefault: {  // 1: 通常(カーポート等、matrix 選択のみ)
  8330. \t\t\t\t\tqty    = 1;
  8331. \t\t\t\t\tgoukei = basePrice + baseCt + optSum;
  8332. \t\t\t\t\tbreak;
  8333. \t\t\t\t}
  8334. \t\t\t}
  8335. \t\t\t// 出口で税込化(pp.price/pp.ct/op_data.price はすべて税抜で保存されている前提)
  8336. \t\t\treturn {
  8337. \t\t\t\tgoukei: toIncTax(goukei),
  8338. \t\t\t\tprice:  toIncTax(price),
  8339. \t\t\t\tct:     toIncTax(ct),
  8340. \t\t\t\topt:    toIncTax(optSum),
  8341. \t\t\t\tqty:    qty,
  8342. \t\t\t};
  8343. \t\t}
  8344. \t\t/**
  8345. \t\t * 寸法文字列から「メートル単位の数値」を抽出する.
  8346. \t\t *
  8347. \t\t * 単位は m / cm / mm を認識し、いずれも m 単位に正規化して返す.
  8348. \t\t * 単位が無い場合は m 単位とみなす(旧 tf データ \"1m\" \"10m\" との互換).
  8349. \t\t * 数値が見つからない場合は 0 を返す(呼び出し側で fallback).
  8350. \t\t *
  8351. \t\t * 例:
  8352. \t\t *   \"1m\"     → 1
  8353. \t\t *   \"100cm\"  → 1   (2026-06 以降の m → cm 正規化に対応)
  8354. \t\t *   \"200cm\"  → 2
  8355. \t\t *   \"5.5m\"   → 5.5
  8356. \t\t *   \"1000mm\" → 1
  8357. \t\t *   \"\"       → 0
  8358. \t\t */
  8359. \t\tfunction parseLen(s) {
  8360. \t\t\tif (!s) return 0;
  8361. \t\t\tvar str = String(s);
  8362. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)\\s*(mm|cm|m)?/i);
  8363. \t\t\tif (!m) return 0;
  8364. \t\t\tvar n = parseFloat(m[1]);
  8365. \t\t\tif (isNaN(n)) return 0;
  8366. \t\t\tvar unit = (m[2] || 'm').toLowerCase();
  8367. \t\t\tif (unit === 'cm') return n / 100;
  8368. \t\t\tif (unit === 'mm') return n / 1000;
  8369. \t\t\treturn n;  // 'm' or no unit
  8370. \t\t}
  8371. \t\t// pp は autoSelectFirstColor 等からも参照するので global にする
  8372. \t\tvar pp = {{ pp|raw }};
  8373. \t\t// sale_type=2 の幅 / 高さ ladder (Twig p_w / p_h を JS で参照するため).
  8374. \t\t// 入力 mm 値を pp の幅・高さバケット文字列にマッピングする際の元データ.
  8375. \t\t// p_w / p_h は連想配列で来ることがあるため Object.values で配列化する.
  8376. \t\tvar PP_W_LADDER = Object.values({{ p_w|default({})|json_encode|raw }} || {});
  8377. \t\tvar PP_H_LADDER = Object.values({{ p_h|default({})|json_encode|raw }} || {});
  8378. \t\t/* ============================================================
  8379. \t\t   sale_type=2 (補助金窓) 専用: 複数タイプ集計 & 補助金計算
  8380. \t\t   ============================================================
  8381. \t\t   - 入力 UI: #window-types-container 配下の .window-type-block
  8382. \t\t   - 補助金根拠: 先進的窓リノベ2026事業
  8383. \t\t     https://window-renovation2026.env.go.jp/construction/inner-window.html
  8384. \t\t   - 価格軸: (subtype, w, h, glass, color) で pp を lookup
  8385. \t\t   - 1 商品 = 1 明細 にまとめ、内訳 JSON を別途保存予定 (cart 連携は後続タスク)
  8386. \t\t   ============================================================ */
  8387. \t\t// 補助金マトリクス: [住宅区分][性能][サイズ区分] → 1 箇所あたり金額 (税抜・端数なし)
  8388. \t\tvar WINDOW_SUBSIDY_MATRIX = {
  8389. \t\t\tdetached:  { // 戸建住宅・延床240㎡以下の非住宅
  8390. \t\t\t\tP: { G: 140000, L: 89000, M: 58000, S: 36000 },
  8391. \t\t\t\tS: { G: 76000,  L: 52000, M: 34000, S: 22000 }
  8392. \t\t\t},
  8393. \t\t\tapartment: { // 低層・中高層集合住宅・240㎡超の非住宅
  8394. \t\t\t\tP: { G: 152000, L: 98000, M: 64000, S: 40000 },
  8395. \t\t\t\tS: { G: 83000,  L: 57000, M: 37000, S: 24000 }
  8396. \t\t\t}
  8397. \t\t};
  8398. \t\t// 住宅区分: 画面 UI (input[name=\"window_housing_type\"]) から取得する.
  8399. \t\t// 既定値は PFC meta_key=\"住宅区分\" を fallback (未設定なら '戸建').
  8400. \t\tvar HOUSING_TYPE_DEFAULT = {{ getProduct_field(Product.id, '住宅区分')|default('戸建')|json_encode|raw }};
  8401. \t\tfunction getCurrentHousingKey() {
  8402. \t\t\tvar el = document.querySelector('input[name=\"window_housing_type\"]:checked');
  8403. \t\t\tvar v  = el ? el.value : HOUSING_TYPE_DEFAULT;
  8404. \t\t\treturn (v === '集合住宅') ? 'apartment' : 'detached';
  8405. \t\t}
  8406. \t\t// 商品シリーズ自動判定 (Product.name から)
  8407. \t\t// 根拠カタログ: YKK AP「ウチリモ」XAAAA-H26-067-1 (2026.04), 同「LiteU」XAAAA-H16-088-2,
  8408. \t\t//              三協アルミ「プラメイクEII」0142_STJ1931L, LIXIL「インプラス」(既知)
  8409. \t\tvar PRODUCT_NAME_RAW = {{ Product.name|default('')|json_encode|raw }};
  8410. \t\tfunction detectProductSeries(name) {
  8411. \t\t\tif (!name) return null;
  8412. \t\t\tif (/ウチリモ/.test(name)) return 'uchirimo';
  8413. \t\t\tif (/プラマード\\s*U/i.test(name)) return 'pramado_u';
  8414. \t\t\tif (/インプラス/.test(name)) return 'inplus';
  8415. \t\t\tif (/プラメイク\\s*EII|プラメイクEII/i.test(name)) return 'plamake_eii';
  8416. \t\t\tif (/LiteU/i.test(name)) return 'lite_u';
  8417. \t\t\treturn null;
  8418. \t\t}
  8419. \t\t// シリーズ上限グレード:
  8420. \t\t//   'P'  = SS/P まで到達可能 (真空断熱ガラス採用シリーズ)
  8421. \t\t//   'S'  = Low-E 複層止まり (真空断熱ガラスのラインなし)
  8422. \t\t//   null = 単板のみ → 補助金対象外
  8423. \t\tvar SERIES_GRADE_CAP = {
  8424. \t\t\tuchirimo:    'P',
  8425. \t\t\tpramado_u:   'P',
  8426. \t\t\tinplus:      'S',
  8427. \t\t\tplamake_eii: 'S',
  8428. \t\t\tlite_u:      null
  8429. \t\t};
  8430. \t\tvar DETECTED_SERIES = detectProductSeries(PRODUCT_NAME_RAW);
  8431. \t\tvar SERIES_GRADE_CAP_VAL = (DETECTED_SERIES !== null && Object.prototype.hasOwnProperty.call(SERIES_GRADE_CAP, DETECTED_SERIES))
  8432. \t\t\t? SERIES_GRADE_CAP[DETECTED_SERIES]
  8433. \t\t\t: undefined;
  8434. \t\t// 商品単位グレード上限 (PFC `meta_key=補助金グレード上限` で個別上書き)
  8435. \t\t// 値: 'P' / 'SS' / 'S' / '対象外' / '無' / 'NONE' / 空文字 (未指定)
  8436. \t\tvar PRODUCT_GRADE_CAP_RAW = {{ getProduct_field(Product.id, '補助金グレード上限')|default('')|json_encode|raw }};
  8437. \t\tfunction normalizeGradeCap(v) {
  8438. \t\t\tif (v === null || v === undefined || v === '') return undefined;
  8439. \t\t\tvar s = String(v).trim().toUpperCase();
  8440. \t\t\tif (s === 'NONE' || s === '対象外' || s === '無') return null;
  8441. \t\t\tif (s === 'P' || s === 'SS') return 'P';
  8442. \t\t\tif (s === 'S') return 'S';
  8443. \t\t\treturn undefined;
  8444. \t\t}
  8445. \t\tvar PRODUCT_GRADE_CAP = normalizeGradeCap(PRODUCT_GRADE_CAP_RAW);
  8446. \t\t// 窓種 (subtype = option1) ごとのグレード上限.
  8447. \t\t// 根拠: YKK AP「ウチリモ」業務用 (XAAAA-H26-067-1) の窓種別ラインナップで
  8448. \t\t//      真空ガラス (Glavenir) の設定有無を確認:
  8449. \t\t//        引違い窓 (2/3/4枚建) / 浴室仕様 引違い窓 / FIX窓        → P 到達可能
  8450. \t\t//        内開き窓 (居室/浴室) / 開き窓テラス / テラスドア類       → 真空ガラスなし → S 止まり
  8451. \t\tfunction detectSubtypeGradeCap(subtype) {
  8452. \t\t\tif (!subtype) return undefined;
  8453. \t\t\tvar s = String(subtype);
  8454. \t\t\tif (/内開|開き窓テラス|テラスドア|開き戸/.test(s)) return 'S';
  8455. \t\t\treturn undefined;
  8456. \t\t}
  8457. \t\t// クリップ: 強さは 'P' > 'S' > null (対象外). cap=null は強制対象外, cap=undefined は無効化なし.
  8458. \t\tfunction clipGradeBy(grade, cap) {
  8459. \t\t\tif (cap === undefined) return grade;
  8460. \t\t\tif (cap === null)      return null;
  8461. \t\t\tif (grade === null)    return null;
  8462. \t\t\tif (cap === 'S' && grade === 'P') return 'S';
  8463. \t\t\treturn grade;
  8464. \t\t}
  8465. \t\tfunction finalizeGlassGrade(raw, subtype) {
  8466. \t\t\tvar g = clipGradeBy(raw, SERIES_GRADE_CAP_VAL);
  8467. \t\t\tg     = clipGradeBy(g,   detectSubtypeGradeCap(subtype));
  8468. \t\t\tg     = clipGradeBy(g,   PRODUCT_GRADE_CAP);
  8469. \t\t\treturn g;
  8470. \t\t}
  8471. \t\t/**
  8472. \t\t * ガラスタイプ名から性能区分 'P' (SS, Uw≤1.1) / 'S' (Uw≤1.5) / null を判別.
  8473. \t\t * null = 補助対象外.
  8474. \t\t *
  8475. \t\t * 根拠: YKK AP「ウチリモ 内窓」業務用カタログ (XAAAA-H26-069-1) で
  8476. \t\t *       P (SS) は真空断熱ガラスのみ、Low-E はアルゴン入りでも S 止まり、
  8477. \t\t *       Low-E ガス無 + 型ガラス / フロストは 2026年4月で対象外、
  8478. \t\t *       が確認できた。アルゴン入り Low-E を P 判定する旧ルールは誤りだった。
  8479. \t\t *
  8480. \t\t * シリーズによっては P がそもそも存在しない (LIXIL インプラスは S 一律)
  8481. \t\t * ため、最終的には PFC で商品単位の上限を上書きできる仕組みが必要。
  8482. \t\t */
  8483. \t\tfunction detectGlassPerformance(glassName) {
  8484. \t\t\tif (!glassName) return null;
  8485. \t\t\tvar n = String(glassName);
  8486. \t\t\t// 補助対象外: 単板 / 和紙調 / 防音 / 防犯 / 型ガラス・フロスト (Low-E ガス無の型は 2026/4 で対象外)
  8487. \t\t\tif (/単ガラス|単板|和紙調|防音|防犯|複層\\/型|型ガラス|フロスト/.test(n)) return null;
  8488. \t\t\t// P (SS): 真空断熱ガラスのみ
  8489. \t\t\tif (/真空断熱/.test(n)) return 'P';
  8490. \t\t\t// S: Low-E 系のみ (アルゴン入りでも S 止まり)
  8491. \t\t\tif (/Low-?E/i.test(n)) return 'S';
  8492. \t\t\t// 一般複層 / ブラインドイン複層 / 複層強化 など Low-E 無しの複層は補助対象外
  8493. \t\t\treturn null;
  8494. \t\t}
  8495. \t\t/**
  8496. \t\t * 幅 mm × 高さ mm からサイズ区分 'G' (≥4.0㎡) / 'L' (2.8-3.9) / 'M' (1.6-2.7) / 'S' (0.2-1.5) / null.
  8497. \t\t * null = 補助対象外 (0.2㎡ 未満).
  8498. \t\t */
  8499. \t\tfunction detectSizeClass(w_mm, h_mm) {
  8500. \t\t\tvar w = parseFloat(w_mm) || 0;
  8501. \t\t\tvar h = parseFloat(h_mm) || 0;
  8502. \t\t\tif (w <= 0 || h <= 0) return null;
  8503. \t\t\tvar area = (w * h) / 1000000.0;
  8504. \t\t\tif (area < 0.2) return null;
  8505. \t\t\tif (area < 1.6) return 'S';
  8506. \t\t\tif (area < 2.8) return 'M';
  8507. \t\t\tif (area < 4.0) return 'L';
  8508. \t\t\treturn 'G';
  8509. \t\t}
  8510. \t\tfunction lookupSubsidyAmount(performance, sizeClass) {
  8511. \t\t\tif (!performance || !sizeClass) return 0;
  8512. \t\t\tvar t = WINDOW_SUBSIDY_MATRIX[getCurrentHousingKey()];
  8513. \t\t\tif (!t || !t[performance]) return 0;
  8514. \t\t\treturn t[performance][sizeClass] || 0;
  8515. \t\t}
  8516. \t\t/**
  8517. \t\t * mm 入力値を ladder バケット文字列に変換する.
  8518. \t\t *   bucketizeMm(1750, [\"100cm まで\",\"150cm まで\",\"200cm まで\",\"300cm まで\"]) → \"200cm まで\"
  8519. \t\t * - 入力が空 or 0 のときはそのまま返す (未入力扱い)
  8520. \t\t * - 入力がラダー最大を超えるときは最大バケットを返す (= 価格上限の保護)
  8521. \t\t * - 入力文字列が既にラダーラベルそのものなら無変換 (互換のため)
  8522. \t\t */
  8523. \t\tfunction bucketizeMm(input, ladder) {
  8524. \t\t\tif (!input && input !== 0) return '';
  8525. \t\t\tif (!ladder || ladder.length === 0) return input;
  8526. \t\t\tvar s = String(input).trim();
  8527. \t\t\tif (s === '') return '';
  8528. \t\t\tif (ladder.indexOf(s) >= 0) return s;
  8529. \t\t\tvar mm = parseMm(s);
  8530. \t\t\tif (mm <= 0) return s;
  8531. \t\t\tvar withMax = ladder.map(function(b) { return { label: b, max: parseMm(b) }; });
  8532. \t\t\twithMax.sort(function(a, b) { return a.max - b.max; });
  8533. \t\t\tfor (var i = 0; i < withMax.length; i++) {
  8534. \t\t\t\tif (mm <= withMax[i].max) return withMax[i].label;
  8535. \t\t\t}
  8536. \t\t\treturn withMax[withMax.length - 1].label;
  8537. \t\t}
  8538. \t\t/**
  8539. \t\t * pp 配列から該当 1 行を返す. 完全一致優先、見つからなければ最初の候補.
  8540. \t\t * 軸: subtype (option1) / w / h / m / c. axisMatch は既存ロジックと同じ.
  8541. \t\t * sale_type=2 では pw_val / ph_val に mm 数値が来るため、内部で bucketizeMm
  8542. \t\t * を通してから既存マッチングに渡す.
  8543. \t\t */
  8544. \t\tfunction lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val) {
  8545. \t\t\tif (!pp || pp.length === 0) return null;
  8546. \t\t\tvar pw_bucket = bucketizeMm(pw_val, PP_W_LADDER);
  8547. \t\t\tvar ph_bucket = bucketizeMm(ph_val, PP_H_LADDER);
  8548. \t\t\tvar axMatch = function(input, value) {
  8549. \t\t\t\treturn input == value || input === '指定なし' || value === '' || value == null;
  8550. \t\t\t};
  8551. \t\t\tvar colMatch = function(input, value) {
  8552. \t\t\t\tif (axMatch(input, value)) return true;
  8553. \t\t\t\tif (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  8554. \t\t\t\t\treturn value.split('/').some(function(s) { return s.trim() === input; });
  8555. \t\t\t\t}
  8556. \t\t\t\treturn false;
  8557. \t\t\t};
  8558. \t\t\tvar candidates = pp.filter(function(el) {
  8559. \t\t\t\treturn axMatch(pw_bucket, el.w)
  8560. \t\t\t\t\t&& axMatch(ph_bucket, el.h)
  8561. \t\t\t\t\t&& axMatch(pm_val, el.m)
  8562. \t\t\t\t\t&& axMatch(subtype, el.option1);
  8563. \t\t\t});
  8564. \t\t\tfor (var i = 0; i < candidates.length; i++) {
  8565. \t\t\t\tif (colMatch(pc_val, candidates[i].c)) return candidates[i];
  8566. \t\t\t}
  8567. \t\t\treturn candidates[0] || null;
  8568. \t\t}
  8569. \t\t/**
  8570. \t\t * \"1000mm\" / \"200cm\" / \"1.0m\" / 単位なし → mm に正規化して返す.
  8571. \t\t * UI 上の「200cm まで」等の文字列をそのまま渡せるようにする.
  8572. \t\t */
  8573. \t\tfunction parseMm(s) {
  8574. \t\t\tif (!s) return 0;
  8575. \t\t\tvar str = String(s);
  8576. \t\t\tvar m = str.match(/(\\d+(?:\\.\\d+)?)/);
  8577. \t\t\tif (!m) return 0;
  8578. \t\t\tvar num = parseFloat(m[1]);
  8579. \t\t\tif (/mm/i.test(str)) return num;
  8580. \t\t\tif (/cm/i.test(str)) return num * 10;
  8581. \t\t\tif (/(^|\\d)\\s*m(\$|\\W)/i.test(str)) return num * 1000;
  8582. \t\t\treturn num;
  8583. \t\t}
  8584. \t\t/**
  8585. \t\t * 1 タイプブロックから入力を読み、pp lookup → 単価・補助金額を計算して返す.
  8586. \t\t * incomplete=true: 軸のどれかが未選択 → 計算しない (UI で「未選択」を示すため).
  8587. \t\t */
  8588. \t\tfunction collectWindowTypeRow(block) {
  8589. \t\t\tvar get = function(axis) {
  8590. \t\t\t\t// radio / checkbox は :checked、それ以外 (number/text) は値そのまま.
  8591. \t\t\t\tvar radio = block.querySelector('input[data-axis=\"' + axis + '\"]:checked');
  8592. \t\t\t\tif (radio) return radio.value;
  8593. \t\t\t\tvar any = block.querySelector('input[data-axis=\"' + axis + '\"]');
  8594. \t\t\t\tif (!any) return '';
  8595. \t\t\t\tif (any.type === 'radio' || any.type === 'checkbox') return '';
  8596. \t\t\t\treturn (any.value || '').trim();
  8597. \t\t\t};
  8598. \t\t\tvar setqtyEl = block.querySelector('input[data-axis=\"setqty\"]');
  8599. \t\t\tvar subtype = get('subtype');
  8600. \t\t\tvar pw_val  = get('pw');
  8601. \t\t\tvar ph_val  = get('ph');
  8602. \t\t\tvar pm_val  = get('pm');
  8603. \t\t\tvar pc_val  = get('pc');
  8604. \t\t\tvar setqty  = setqtyEl ? Math.max(1, parseInt(setqtyEl.value) || 1) : 1;
  8605. \t\t\tvar row = {
  8606. \t\t\t\tsubtype: subtype, pw: pw_val, ph: ph_val, pm: pm_val, pc: pc_val, setqty: setqty,
  8607. \t\t\t\tunit_price_exc: 0, unit_ct_exc: 0, subsidy: 0,
  8608. \t\t\t\tsize_class: null, glass_perf: null,
  8609. \t\t\t\tincomplete: false
  8610. \t\t\t};
  8611. \t\t\t// p_option1 / p_w / p_h / p_m / color のいずれかが商品データに無いときは未選択でも完了扱いにする.
  8612. \t\t\t// (例: 商品によっては subtype が無い場合がある)
  8613. \t\t\tvar hasSubtype = !!block.querySelector('input[data-axis=\"subtype\"]');
  8614. \t\t\tvar hasPw      = !!block.querySelector('input[data-axis=\"pw\"]');
  8615. \t\t\tvar hasPh      = !!block.querySelector('input[data-axis=\"ph\"]');
  8616. \t\t\tvar hasPm      = !!block.querySelector('input[data-axis=\"pm\"]');
  8617. \t\t\tvar hasPc      = !!block.querySelector('input[data-axis=\"pc\"]');
  8618. \t\t\tif ((hasSubtype && !subtype) || (hasPw && !pw_val) || (hasPh && !ph_val)
  8619. \t\t\t    || (hasPm && !pm_val)  || (hasPc && !pc_val)) {
  8620. \t\t\t\trow.incomplete = true;
  8621. \t\t\t\treturn row;
  8622. \t\t\t}
  8623. \t\t\tvar ppRow = lookupPpRow(subtype, pw_val, ph_val, pm_val, pc_val);
  8624. \t\t\tif (ppRow) {
  8625. \t\t\t\trow.unit_price_exc = parseInt(ppRow.price) || 0;
  8626. \t\t\t\trow.unit_ct_exc    = parseInt(ppRow.ct)    || 0;
  8627. \t\t\t}
  8628. \t\t\t// ガラス名検出 → シリーズ上限 → subtype 上限 → 商品上限 の順で min クリップ.
  8629. \t\t\t// 例: LiteU (SERIES_GRADE_CAP_VAL=null) は Low-E でも null に落ちて補助対象外.
  8630. \t\t\t// 例: ウチリモの「内開き窓」subtype は真空ガラスでも S に落ちる.
  8631. \t\t\trow.glass_perf = finalizeGlassGrade(detectGlassPerformance(pm_val), subtype);
  8632. \t\t\trow.size_class = detectSizeClass(parseMm(pw_val), parseMm(ph_val));
  8633. \t\t\trow.subsidy    = lookupSubsidyAmount(row.glass_perf, row.size_class);
  8634. \t\t\treturn row;
  8635. \t\t}
  8636. \t\t/**
  8637. \t\t * sale_type=2 用集計: 全タイプから合計を出し DOM 更新.
  8638. \t\t * 計算式 (税抜→税込で出口で 1.10 倍):
  8639. \t\t *   商品金額 = Σ(各タイプ単価 × set_qty)
  8640. \t\t *   基本工事費 = 1 回分 (各タイプ pp.ct のうち最初に得た非ゼロ値)
  8641. \t\t *   補助金合計 = Σ(各タイプ補助金 × set_qty)
  8642. \t\t *   実質支払額 = (商品+ct+option) 税込 - 補助金合計
  8643. \t\t */
  8644. \t\tfunction recalcAllForSaleType2() {
  8645. \t\t\tif (typeof SALE_TYPE_ID === 'undefined' || SALE_TYPE_ID != 2) return;
  8646. \t\t\tif (!pp || pp.length === 0) {
  8647. \t\t\t\t\$('#mitsumori_message').text('価格データ準備中');
  8648. \t\t\t\t\$('#mitsumori_btn').hide();
  8649. \t\t\t\t['#mitsumori_goukei','#mitsumori_off','#mitsumori_price','#maker_price',
  8650. \t\t\t\t '#mitsumori_ct','#mitsumori_option','#mitsumori_kei','#mitsumori_shoukei','#mitsumori_tax']
  8651. \t\t\t\t .forEach(function(s){ \$(s).text('---円'); });
  8652. \t\t\t\treturn;
  8653. \t\t\t}
  8654. \t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  8655. \t\t\tif (blocks.length === 0) return;
  8656. \t\t\tvar rows = [];
  8657. \t\t\tvar hasIncomplete = false;
  8658. \t\t\tvar baseCt = 0;
  8659. \t\t\tvar hasAnyPriced = false;
  8660. \t\t\tblocks.forEach(function(b) {
  8661. \t\t\t\tvar r = collectWindowTypeRow(b);
  8662. \t\t\t\trows.push({ block: b, row: r });
  8663. \t\t\t\tif (r.incomplete) hasIncomplete = true;
  8664. \t\t\t\tif (r.unit_ct_exc > 0 && baseCt === 0) baseCt = r.unit_ct_exc;
  8665. \t\t\t\tif (r.unit_price_exc > 0) hasAnyPriced = true;
  8666. \t\t\t\tvar subSpan = b.querySelector('.wt-subsidy-amount');
  8667. \t\t\t\tif (subSpan) subSpan.textContent = r.incomplete ? '―' : Math.round(r.subsidy * r.setqty).toLocaleString();
  8668. \t\t\t});
  8669. \t\t\tif (hasIncomplete || !hasAnyPriced) {
  8670. \t\t\t\t\$('#mitsumori_message').text('窓タイプを選択してください');
  8671. \t\t\t\t\$('#mitsumori_btn').hide();
  8672. \t\t\t\treturn;
  8673. \t\t\t}
  8674. \t\t\tvar ops = [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10];
  8675. \t\t\tvar purchaseOnly = ops.some(function(v){ return v === '商品購入のみ'; });
  8676. \t\t\tvar sumPriceExc = 0, sumSubsidy = 0, totalPanes = 0;
  8677. \t\t\trows.forEach(function(item) {
  8678. \t\t\t\tvar r = item.row;
  8679. \t\t\t\tsumPriceExc += r.unit_price_exc * r.setqty;
  8680. \t\t\t\tsumSubsidy  += r.subsidy * r.setqty;
  8681. \t\t\t\tif (r.unit_price_exc > 0) totalPanes += r.setqty;
  8682. \t\t\t});
  8683. \t\t\t// 内窓 工事費(顧客最終回答): 1枚目 22,000円 + 2枚目以降 1枚あたり +5,000円(税込表示額)。
  8684. \t\t\t// 既存パイプライン整合のため税抜(ctExc)も用意(税行 taxAmt 用)。商品購入のみは 0。
  8685. \t\t\tvar WINDOW_CT_BASE = 22000, WINDOW_CT_ADD = 5000;
  8686. \t\t\tvar ctIncTarget = purchaseOnly ? 0 : (WINDOW_CT_BASE + Math.max(0, totalPanes - 1) * WINDOW_CT_ADD);
  8687. \t\t\tvar ctExc  = purchaseOnly ? 0 : Math.round(ctIncTarget / (1 + TAX_RATE));
  8688. \t\t\tvar optExc = purchaseOnly ? 0 : (collectOptions().total || 0);
  8689. \t\t\tvar sumPriceInc = Math.round(sumPriceExc * (1 + TAX_RATE));
  8690. \t\t\tvar ctInc       = ctIncTarget;
  8691. \t\t\tvar optInc      = Math.round(optExc * (1 + TAX_RATE));
  8692. \t\t\tvar goukeiInc   = sumPriceInc + ctInc + optInc;
  8693. \t\t\t// 窓リノベ2026 申請条件:
  8694. \t\t\t//   - 補助金合計 ≥ 50,000 円 (5 万円未満は申請不可 → 還元 0 円扱い)
  8695. \t\t\t//   - 1 戸あたり上限 1,000,000 円 (住宅・非住宅240㎡以下)
  8696. \t\t\t//     ※ 非住宅 240㎡超の 10,000,000 円上限は対象外 (商品設計時に別扱い想定)
  8697. \t\t\tvar SUBSIDY_MIN_AMOUNT = 50000;
  8698. \t\t\tvar SUBSIDY_MAX_PER_UNIT = 1000000;
  8699. \t\t\tvar subsidyRawSum = sumSubsidy;
  8700. \t\t\tvar subsidyEligible = subsidyRawSum >= SUBSIDY_MIN_AMOUNT;
  8701. \t\t\tvar subsidyAmt = 0;
  8702. \t\t\tvar subsidyNote = '';
  8703. \t\t\tif (subsidyEligible) {
  8704. \t\t\t\tif (subsidyRawSum > SUBSIDY_MAX_PER_UNIT) {
  8705. \t\t\t\t\tsubsidyAmt = SUBSIDY_MAX_PER_UNIT;
  8706. \t\t\t\t\tsubsidyNote = '※補助上限 ' + SUBSIDY_MAX_PER_UNIT.toLocaleString()
  8707. \t\t\t\t\t\t+ '円 超過分は控除対象外(補助金合計 ' + subsidyRawSum.toLocaleString() + '円)';
  8708. \t\t\t\t} else {
  8709. \t\t\t\t\tsubsidyAmt = subsidyRawSum;
  8710. \t\t\t\t}
  8711. \t\t\t} else if (subsidyRawSum > 0) {
  8712. \t\t\t\tsubsidyNote = '※補助金合計が 5 万円未満のため申請対象外です('
  8713. \t\t\t\t\t+ subsidyRawSum.toLocaleString() + '円)';
  8714. \t\t\t} else if (SERIES_GRADE_CAP_VAL === null) {
  8715. \t\t\t\t// LiteU 等の単板構成シリーズ: グレード判定で必ず null になる
  8716. \t\t\t\tsubsidyNote = '※本商品は補助金(先進的窓リノベ2026事業)対象外です';
  8717. \t\t\t} else if (PRODUCT_GRADE_CAP === null) {
  8718. \t\t\t\tsubsidyNote = '※本商品は補助金対象外として登録されています';
  8719. \t\t\t}
  8720. \t\t\tvar implementedInc = Math.max(0, goukeiInc - subsidyAmt);
  8721. \t\t\tvar taxAmt      = Math.round((sumPriceExc + ctExc + optExc) * TAX_RATE);
  8722. \t\t\t\$('#mitsumori_message').text(subsidyNote);
  8723. \t\t\t\$('#mitsumori_btn').show();
  8724. \t\t\t\$('#mitsumori_goukei').text(goukeiInc.toLocaleString() + '円');
  8725. \t\t\t\$('#mitsumori_price').text(sumPriceInc.toLocaleString() + '円');
  8726. \t\t\t\$('#mitsumori_ct').text(ctInc.toLocaleString() + '円');
  8727. \t\t\t\$('#mitsumori_option').text(optInc.toLocaleString() + '円');
  8728. \t\t\t\$('#mitsumori_off').text((subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円');
  8729. \t\t\t\$('#maker_price').text('---円'); // 補助金窓では未使用
  8730. \t\t\t\$('#mitsumori_kei').text(goukeiInc.toLocaleString() + '円');
  8731. \t\t\t\$('#mitsumori_shoukei').text(implementedInc.toLocaleString() + '円');
  8732. \t\t\t\$('#mitsumori_tax').text(taxAmt.toLocaleString() + '円');
  8733. \t\t\t// 内訳を mitsumori_json に詰めて hidden input にセット (PDF / カート連携用)
  8734. \t\t\tvar window_types = rows.map(function(item) {
  8735. \t\t\t\tvar r = item.row;
  8736. \t\t\t\t// 幅 / 高さは数値入力 (mm) が来るので \"1750mm\" 形式で保存する.
  8737. \t\t\t\t// 古い radio 由来の \"200cm まで\" 形式が来た場合はそのまま保存して互換.
  8738. \t\t\t\tvar w_mm = parseMm(r.pw);
  8739. \t\t\t\tvar h_mm = parseMm(r.ph);
  8740. \t\t\t\tvar w_save = (w_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.pw))) ? (w_mm + 'mm') : r.pw;
  8741. \t\t\t\tvar h_save = (h_mm > 0 && /^\\s*\\d+(?:\\.\\d+)?\\s*\$/.test(String(r.ph))) ? (h_mm + 'mm') : r.ph;
  8742. \t\t\t\treturn {
  8743. \t\t\t\t\tsubtype:        r.subtype,
  8744. \t\t\t\t\tw:              w_save,
  8745. \t\t\t\t\th:              h_save,
  8746. \t\t\t\t\tglass:          r.pm,
  8747. \t\t\t\t\tcolor:          r.pc,
  8748. \t\t\t\t\tsetqty:         r.setqty,
  8749. \t\t\t\t\tunit_price_inc: Math.round(r.unit_price_exc * (1 + TAX_RATE)),
  8750. \t\t\t\t\tline_total_inc: Math.round(r.unit_price_exc * r.setqty * (1 + TAX_RATE)),
  8751. \t\t\t\t\tsize_class:     r.size_class,
  8752. \t\t\t\t\tglass_perf:     r.glass_perf,
  8753. \t\t\t\t\tsubsidy_unit:   r.subsidy,
  8754. \t\t\t\t\tsubsidy_total:  r.subsidy * r.setqty
  8755. \t\t\t\t};
  8756. \t\t\t});
  8757. \t\t\tvar opCalc2 = collectOptions();
  8758. \t\t\tvar mitsumori_json = {
  8759. \t\t\t\t\"mitsumori_goukei\": goukeiInc.toLocaleString() + '円',
  8760. \t\t\t\t\"mitsumori_price\":  sumPriceInc.toLocaleString() + '円',
  8761. \t\t\t\t\"mitsumori_ct\":     ctInc.toLocaleString() + '円',
  8762. \t\t\t\t\"mitsumori_option\": optInc.toLocaleString() + '円',
  8763. \t\t\t\t\"mitsumori_off\":    (subsidyAmt > 0 ? '-' : '') + subsidyAmt.toLocaleString() + '円',
  8764. \t\t\t\t\"maker_price\":      '---円',
  8765. \t\t\t\t\"product_id\":       {{ Product.id }},
  8766. \t\t\t\t\"sale_type\":        SALE_TYPE_ID,
  8767. \t\t\t\t\"housing_key\":      getCurrentHousingKey(),
  8768. \t\t\t\t\"series_key\":       DETECTED_SERIES,
  8769. \t\t\t\t\"series_grade_cap\": (SERIES_GRADE_CAP_VAL === undefined) ? null : SERIES_GRADE_CAP_VAL,
  8770. \t\t\t\t\"product_grade_cap\":(PRODUCT_GRADE_CAP    === undefined) ? null : PRODUCT_GRADE_CAP,
  8771. \t\t\t\t\"window_types\":     window_types,
  8772. \t\t\t\t\"subsidy_total\":    subsidyAmt,
  8773. \t\t\t\t\"subsidy_raw\":      subsidyRawSum,
  8774. \t\t\t\t\"subsidy_eligible\": subsidyEligible,
  8775. \t\t\t\t\"subsidy_note\":     subsidyNote,
  8776. \t\t\t\t\"op_items\":         opCalc2.items
  8777. \t\t\t};
  8778. \t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  8779. \t\t\trenderWindowTypesModalRows(window_types, subsidyAmt);
  8780. \t\t}
  8781. \t\t/**
  8782. \t\t * sale_type=2 用: 見積モーダル明細テーブルを window_types で動的展開.
  8783. \t\t * - 既存の商品名行 (1 行目) は hide() し、各タイプ行を上に挿入
  8784. \t\t * - 基本工事費行はそのまま (#mitsumori_ct_01 / _02 が更新されている)
  8785. \t\t * - 補助金 (割引額) 行を末尾に追加
  8786. \t\t * - 既存の renderOptionDetailRows と共存できるよう class で区別
  8787. \t\t */
  8788. \t\tfunction renderWindowTypesModalRows(window_types, subsidyAmt) {
  8789. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  8790. \t\t\tif (!\$tbody.length) return;
  8791. \t\t\t// 既存の動的行を全削除 (opt-row は既存実装、wt-row / wt-subsidy-row は今回追加)
  8792. \t\t\t\$tbody.find('tr.wt-row, tr.wt-subsidy-row').remove();
  8793. \t\t\tvar \$itemRow = \$tbody.find('tr').first();
  8794. \t\t\tvar fmt = new Intl.NumberFormat('ja-JP');
  8795. \t\t\tif (!window_types || window_types.length === 0) {
  8796. \t\t\t\t// 集計対象なし → 商品名行を表示に戻す
  8797. \t\t\t\t\$itemRow.show();
  8798. \t\t\t\treturn;
  8799. \t\t\t}
  8800. \t\t\twindow_types.forEach(function(wt, i) {
  8801. \t\t\t\tvar label = '窓タイプ' + (i + 1) + ':'
  8802. \t\t\t\t\t+ (wt.subtype || '') + ' / '
  8803. \t\t\t\t\t+ (wt.w || '') + '×' + (wt.h || '') + ' / '
  8804. \t\t\t\t\t+ (wt.glass || '') + ' / '
  8805. \t\t\t\t\t+ (wt.color || '');
  8806. \t\t\t\tvar \$tr = \$('<tr class=\"wt-row\"></tr>')
  8807. \t\t\t\t\t.append('<td>' + label + '</td>')
  8808. \t\t\t\t\t.append('<td>' + wt.setqty + '</td>')
  8809. \t\t\t\t\t.append('<td>セット</td>')
  8810. \t\t\t\t\t.append('<td>' + fmt.format(wt.unit_price_inc) + '円</td>')
  8811. \t\t\t\t\t.append('<td>' + fmt.format(wt.line_total_inc) + '円</td>');
  8812. \t\t\t\t\$itemRow.before(\$tr);
  8813. \t\t\t});
  8814. \t\t\t// 元の商品名行は複数タイプに置換されたので非表示
  8815. \t\t\t\$itemRow.hide();
  8816. \t\t\t// 補助金(割引額)行を末尾に追加
  8817. \t\t\tif (subsidyAmt > 0) {
  8818. \t\t\t\tvar \$subRow = \$('<tr class=\"wt-subsidy-row\"></tr>')
  8819. \t\t\t\t\t.append('<td>補助金(割引額)</td>')
  8820. \t\t\t\t\t.append('<td>1</td>')
  8821. \t\t\t\t\t.append('<td>式</td>')
  8822. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>')
  8823. \t\t\t\t\t.append('<td>-' + fmt.format(subsidyAmt) + '円</td>');
  8824. \t\t\t\t\$tbody.append(\$subRow);
  8825. \t\t\t}
  8826. \t\t}
  8827. \t\t// 公開: onWindowTypeAxisChange (UI 骨格 task 1) からも呼ばれる
  8828. \t\twindow.recalcAll = recalcAllForSaleType2;
  8829. \t\t// 公開: ガラス選択肢が補助金対象か (窓タイプブロック生成時のバッジ判定に使う).
  8830. \t\t// subtype は P→S に落とすことはあっても null にはしないため、性能区分の
  8831. \t\t// 対象/対象外は subtype に依存しない。ここでは series/product 上限のみ適用し、
  8832. \t\t// finalizeGlassGrade が null でなければ「補助金対象ガラス」と判定する。
  8833. \t\twindow.glassYieldsSubsidy = function(glassName) {
  8834. \t\t\tif (!glassName) return false;
  8835. \t\t\treturn finalizeGlassGrade(detectGlassPerformance(glassName), '') !== null;
  8836. \t\t};
  8837. \t\tfunction mitsumori_simulation(type , value_id){
  8838. \t\t\t// sale_type=2 (補助金窓) は複数タイプ集計 UI に統合済み. 既存 mitsumori_simulation は使わない.
  8839. \t\t\tif (typeof SALE_TYPE_ID !== 'undefined' && SALE_TYPE_ID == 2) {
  8840. \t\t\t\t// type/value_id が op\\d+ (施工オプション) の場合はグローバル変数を先に更新
  8841. \t\t\t\tif (type && /^op\\d+\$/.test(type) && value_id) {
  8842. \t\t\t\t\tvar v = \$('#'+value_id).val();
  8843. \t\t\t\t\tif (type === 'op0')  op0  = v;
  8844. \t\t\t\t\tif (type === 'op1')  op1  = v;
  8845. \t\t\t\t\tif (type === 'op2')  op2  = v;
  8846. \t\t\t\t\tif (type === 'op3')  op3  = v;
  8847. \t\t\t\t\tif (type === 'op4')  op4  = v;
  8848. \t\t\t\t\tif (type === 'op5')  op5  = v;
  8849. \t\t\t\t\tif (type === 'op6')  op6  = v;
  8850. \t\t\t\t\tif (type === 'op7')  op7  = v;
  8851. \t\t\t\t\tif (type === 'op8')  op8  = v;
  8852. \t\t\t\t\tif (type === 'op9')  op9  = v;
  8853. \t\t\t\t\tif (type === 'op10') op10 = v;
  8854. \t\t\t\t}
  8855. \t\t\t\trecalcAllForSaleType2();
  8856. \t\t\t\treturn;
  8857. \t\t\t}
  8858. \t\t\t// 価格データ未登録 (pp 行 0 件) の商品は axis 入力に依存せず
  8859. \t\t\t// 「価格データ準備中」を表示して終了する.
  8860. \t\t\t// (例: scrape 未対象の新規商品 — um のウチリモ 7487/7488 等)
  8861. \t\t\tif (!pp || pp.length === 0) {
  8862. \t\t\t\t\$('#mitsumori_message').text(\"価格データ準備中\");
  8863. \t\t\t\t\$('#mitsumori_btn').hide();
  8864. \t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  8865. \t\t\t\t\$('#mitsumori_off').text(\"---円\");
  8866. \t\t\t\t\$('#mitsumori_price').text(\"---円\");
  8867. \t\t\t\t\$('#maker_price').text(\"---円\");
  8868. \t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  8869. \t\t\t\t\$('#mitsumori_option').text(\"---円\");
  8870. \t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  8871. \t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  8872. \t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  8873. \t\t\t\treturn;
  8874. \t\t\t}
  8875. \t\t\tif(type == \"pw\"){
  8876. \t\t\t\tpw = \$('#'+value_id).val();
  8877. \t\t\t}
  8878. \t\t\tif(type == \"pd\"){
  8879. \t\t\t\tpd = \$('#'+value_id).val();
  8880. \t\t\t}
  8881. \t\t\tif(type == \"ph\"){
  8882. \t\t\t\tph = \$('#'+value_id).val();
  8883. \t\t\t}
  8884. \t\t\tif(type == \"pm\"){
  8885. \t\t\t\tpm = \$('#'+value_id).val();
  8886. \t\t\t}
  8887. \t\t\tif(type == \"pc\"){
  8888. \t\t\t\tpc = \$('#'+value_id).val();
  8889. \t\t\t}
  8890. \t\t\tif(type == \"option1\"){
  8891. \t\t\t\toption1 = \$('#'+value_id).val();
  8892. \t\t\t}
  8893. \t\t\tif(type == \"option2\"){
  8894. \t\t\t\toption2 = \$('#'+value_id).val();
  8895. \t\t\t}
  8896. \t\t\tif(type == \"op0\"){ op0 = \$('#'+value_id).val(); }
  8897. \t\t\tif(type == \"op1\"){ op1 = \$('#'+value_id).val(); }
  8898. \t\t\tif(type == \"op2\"){ op2 = \$('#'+value_id).val(); }
  8899. \t\t\tif(type == \"op3\"){ op3 = \$('#'+value_id).val(); }
  8900. \t\t\tif(type == \"op4\"){ op4 = \$('#'+value_id).val(); }
  8901. \t\t\tif(type == \"op5\"){ op5 = \$('#'+value_id).val(); }
  8902. \t\t\tif(type == \"op6\"){ op6 = \$('#'+value_id).val(); }
  8903. \t\t\tif(type == \"op7\"){ op7 = \$('#'+value_id).val(); }
  8904. \t\t\tif(type == \"op8\"){ op8 = \$('#'+value_id).val(); }
  8905. \t\t\tif(type == \"op9\"){ op9 = \$('#'+value_id).val(); }
  8906. \t\t\tif(type == \"op10\"){ op10 = \$('#'+value_id).val(); }
  8907. \t\t\t// op0 が「商品購入のみ」のとき、他のオプション (op1..op10) を disable 化.
  8908. \t\t\t// 価格計算側 (calcGoukei の purchaseOnly 分岐) は既にゼロ化しているが、
  8909. \t\t\t// UI で選択可能に見えるとユーザーが混乱するため radio を完全に無効化する.
  8910. \t\t\t(function applyPurchaseOnlyUI() {
  8911. \t\t\t\tvar isPurchaseOnly = (op0 === '商品購入のみ');
  8912. \t\t\t\tfor (var k = 1; k <= 10; k++) {
  8913. \t\t\t\t\tvar \$inputs = \$('input[name=\"op' + k + '\"]');
  8914. \t\t\t\t\tif (\$inputs.length === 0) continue;
  8915. \t\t\t\t\t\$inputs.prop('disabled', isPurchaseOnly);
  8916. \t\t\t\t\tvar \$group = \$inputs.first().closest('.form-group');
  8917. \t\t\t\t\t\$group.css({
  8918. \t\t\t\t\t\t'opacity':        isPurchaseOnly ? '0.4'  : '1',
  8919. \t\t\t\t\t\t'pointer-events': isPurchaseOnly ? 'none' : 'auto'
  8920. \t\t\t\t\t});
  8921. \t\t\t\t}
  8922. \t\t\t})();
  8923. \t\t\t// 全 type 共通: 該当 radio を checked にし、ボタンの is-selected を付け替え + ラベル更新.
  8924. \t\t\t//   value_id が指定されていて、対応する DOM 要素が opt-btn 配下にあれば適用する.
  8925. \t\t\t//   (icheck-danger 形式から opt-btn 形式に統一した際、option1/option2/pw/pd/ph/pm/pc 等の
  8926. \t\t\t//    クリックで is-selected が更新されない不具合があったため、op\\d+ 限定の処理を一般化)
  8927. \t\t\tif (value_id) {
  8928. \t\t\t\tvar \$clicked = \$('#' + value_id);
  8929. \t\t\t\tif (\$clicked.length && \$clicked.closest('.opt-btn').length) {
  8930. \t\t\t\t\t\$clicked.prop('checked', true);
  8931. \t\t\t\t\tvar groupName = \$clicked.attr('name');
  8932. \t\t\t\t\t\$('input[name=\"' + groupName + '\"]').closest('.opt-btn').removeClass('is-selected');
  8933. \t\t\t\t\t\$clicked.closest('.opt-btn').addClass('is-selected');
  8934. \t\t\t\t\tvar \$group = \$clicked.closest('.form-group');
  8935. \t\t\t\t\tvar \$label = \$group.find('.rp-section-label');
  8936. \t\t\t\t\tif (\$label.length) {
  8937. \t\t\t\t\t\tvar labelText = \$label.text().split(':')[0].trim();
  8938. \t\t\t\t\t\t\$label.html(labelText + ': <span>' + \$clicked.val() + '</span>');
  8939. \t\t\t\t\t}
  8940. \t\t\t\t\t// op_data の price=0 & 解体/撤去/設置場所 オプションの場合、ON 選択時に「現場調査後に正式お見積もり」文言を表示.
  8941. \t\t\t\t\t//   (twig 側で is_removal_unknown ブロックを描画済み。display 切替のみ JS で行う)
  8942. \t\t\t\t\tif (/^op\\d+\$/.test(type)) {
  8943. \t\t\t\t\t\tvar opIdx = type.replace('op', '');
  8944. \t\t\t\t\t\tvar opEntry = op_data[parseInt(opIdx)];
  8945. \t\t\t\t\t\tif (opEntry) {
  8946. \t\t\t\t\t\t\tvar \$note = \$group.find('.opt-survey-note[data-op-idx=\"' + opIdx + '\"]');
  8947. \t\t\t\t\t\t\tif (\$note.length) {
  8948. \t\t\t\t\t\t\t\tvar isOn = (\$clicked.val() === opEntry.on);
  8949. \t\t\t\t\t\t\t\t\$note.toggle(isOn);
  8950. \t\t\t\t\t\t\t}
  8951. \t\t\t\t\t\t}
  8952. \t\t\t\t\t\t// wd (sale_type=5) のステップ / デッキフェンス用の注記もここで切替.
  8953. \t\t\t\t\t\t//   ステップ → deck_step (op0 だが op_data 範囲外), 必要 選択時に表示.
  8954. \t\t\t\t\t\tvar radioName = \$clicked.attr('name');
  8955. \t\t\t\t\t\tif (radioName === 'deck_step') {
  8956. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-step').toggle(\$clicked.val() === '必要');
  8957. \t\t\t\t\t\t} else if (radioName === 'deck_fence') {
  8958. \t\t\t\t\t\t\t\$group.find('.opt-survey-note-wd-fence').toggle(\$clicked.val() === '必要');
  8959. \t\t\t\t\t\t}
  8960. \t\t\t\t\t}
  8961. \t\t\t\t}
  8962. \t\t\t}
  8963. \t\t\t// 必須項目チェックは sale_type 1 系(カーポート/物置/フェンスなど価格マトリクス必要)に限定
  8964. \t\t\tvar requireMatrix = (SALE_TYPE_ID == 1 || SALE_TYPE_ID == 2 || SALE_TYPE_ID == 3 || SALE_TYPE_ID == 4 || SALE_TYPE_ID == 5 || SALE_TYPE_ID == 6 || SALE_TYPE_ID == 7 || SALE_TYPE_ID == 9);
  8965. \t\t\t// sale_type=3 (物置・ゴミステーション・照明 等) では「素材」を選択肢として扱わない.
  8966. \t\t\t//   - mo/gs/sy は m が \"指定なし\" など名目的にしか入っていない
  8967. \t\t\t//   - sl は m が空のままで matrix に行が来る
  8968. \t\t\t//   そのため pm の必須チェックを sale_type=3 でスキップする。
  8969. \t\t\tvar pmRequired = (SALE_TYPE_ID != 3);
  8970. \t\t\tif (requireMatrix) {
  8971. \t\t\t\tif(pmRequired && pm == \"\"){
  8972. \t\t\t\t\t\$('#mitsumori_message').text(\"素材を選択してください\");
  8973. \t\t\t\t}
  8974. \t\t\t\tif(ph == \"\"){
  8975. \t\t\t\t\t\$('#mitsumori_message').text(\"高さを選択してください\");
  8976. \t\t\t\t}
  8977. \t\t\t\tif(pd == \"\"){
  8978. \t\t\t\t\t\$('#mitsumori_message').text(\"奥行きを選択してください\");
  8979. \t\t\t\t}
  8980. \t\t\t\tif(pw == \"\"){
  8981. \t\t\t\t\t\$('#mitsumori_message').text(\"幅を選択してください\");
  8982. \t\t\t\t}
  8983. \t\t\t\tif(pc == \"\"){
  8984. \t\t\t\t\t\$('#mitsumori_message').text(\"カラーを選択してください\");
  8985. \t\t\t\t\t\$('#mitsumori_btn').hide();
  8986. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  8987. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  8988. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  8989. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  8990. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  8991. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  8992. \t\t\t\t}
  8993. \t\t\t}
  8994. \t\t\tif(pw != \"\" && pd != \"\" && ph != \"\" && (!pmRequired || pm != \"\") && pc != \"\"){
  8995. \t\t\t\t\$('#mitsumori_btn').show();
  8996. \t\t\t\t// 入力コンテキスト(sale_type 別パラメータ)
  8997. \t\t\t\tvar ctx = {
  8998. \t\t\t\t\tset_count:    parseInt(\$('#set_count').val())    || 1,
  8999. \t\t\t\t\tdaisu:        parseInt(\$('#daisu').val())        || 1,
  9000. \t\t\t\t\tmaisu:        parseInt(\$('#maisu').val())        || 3,
  9001. \t\t\t\t\tsuuryou:      parseInt(\$('#suuryou').val())      || 1,
  9002. \t\t\t\t\tarea:         (function(){
  9003. \t\t\t\t\t\t// tf(人工芝): 施工サイズ 縦(m)×横(m) から面積を算出し #area に反映.
  9004. \t\t\t\t\t\tvar L = parseFloat(\$('#tf_len').val()) || 0;
  9005. \t\t\t\t\t\tvar W = parseFloat(\$('#tf_wid').val()) || 0;
  9006. \t\t\t\t\t\tif (L > 0 && W > 0) { var a = L * W; \$('#area').val(a); return a; }
  9007. \t\t\t\t\t\treturn parseFloat(\$('#area').val()) || 0;
  9008. \t\t\t\t\t})(),
  9009. \t\t\t\t\ttf_len:       parseFloat(\$('#tf_len').val())     || 0,
  9010. \t\t\t\t\ttf_wid:       parseFloat(\$('#tf_wid').val())     || 0,
  9011. \t\t\t\t\ttf_qty:       parseInt(\$('#tf_qty').val())       || 1,
  9012. \t\t\t\t\tquantityOnly: parseInt(\$('#quantity_only').val())|| 1,
  9013. \t\t\t\t\tmado_w:       \$('#mado_w').val() || '',
  9014. \t\t\t\t\tmado_h:       \$('#mado_h').val() || '',
  9015. \t\t\t\t\tmado_type:    \$('input[name=mado_type]:checked').val()  || '',
  9016. \t\t\t\t\tglass_type:   \$('input[name=glass_type]:checked').val() || '',
  9017. \t\t\t\t\tdeck_step:    \$('input[name=deck_step]:checked').val()  || '',
  9018. \t\t\t\t\tdeck_fence:   \$('input[name=deck_fence]:checked').val() || '',
  9019. \t\t\t\t};
  9020. \t\t\t\t// 施工オプション集計(残土処理を含む)
  9021. \t\t\t\tvar opCalc = collectOptions();
  9022. \t\t\t\tvar pp_matched = false;
  9023. \t\t\t\t// 各軸の汎用 axisMatch:
  9024. \t\t\t\t//   user 選択 == matrix 値 / user \"指定なし\" / matrix 値が空
  9025. \t\t\t\tvar axisMatch = function(input, value){
  9026. \t\t\t\t    return input == value || input == \"指定なし\" || value === \"\" || value == null;
  9027. \t\t\t\t};
  9028. \t\t\t\t// 色専用マッチャー: scraper のデータ形式に合わせて拡張する
  9029. \t\t\t\t//   1. 完全一致 / \"指定なし\" / 値が空 → 真 (axisMatch と同じ)
  9030. \t\t\t\t//   2. matrix 値が \"色1/色2/色3\" の形 (同価格グループ) → split して user 選択が含まれれば真
  9031. \t\t\t\t// scraper のロジック (scraper_price.py L765-779):
  9032. \t\t\t\t//   全色同価格 → c=\"\"、価格違いグループあり → 各 group を \"/\" 結合した色名で 1 行
  9033. \t\t\t\tvar colorMatch = function(input, value){
  9034. \t\t\t\t    if (axisMatch(input, value)) return true;
  9035. \t\t\t\t    if (typeof value === 'string' && value.indexOf('/') !== -1 && input) {
  9036. \t\t\t\t        var parts = value.split('/');
  9037. \t\t\t\t        for (var idx = 0; idx < parts.length; idx++) {
  9038. \t\t\t\t            if (parts[idx].trim() === input) return true;
  9039. \t\t\t\t        }
  9040. \t\t\t\t    }
  9041. \t\t\t\t    return false;
  9042. \t\t\t\t};
  9043. \t\t\t\t// 他軸 (w/d/h/m + option1/option2) でマッチする pp 行を抽出.
  9044. \t\t\t\t// option1/option2 は um の subtype 等で使われる. axisMatch は free_area 側が
  9045. \t\t\t\t// 空のとき真を返すので、um 以外のカテゴリ (option 軸を使わない) でも影響なし.
  9046. \t\t\t\tvar candidates = pp.filter(function(el){
  9047. \t\t\t\t    return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m)
  9048. \t\t\t\t        && axisMatch(option1, el.option1) && axisMatch(option2, el.option2);
  9049. \t\t\t\t});
  9050. \t\t\t\t// フォールバック: 全軸一致が 0 件のときに限り option1/option2 を無視して再マッチ。
  9051. \t\t\t\t// 玄関ドア等で option1(なし/ランマ付き)・option2(◯◯タイプ) が pm(開き方) から
  9052. \t\t\t\t// 導出可能な冗長軸で、未選択だと全軸 AND 一致を満たせず価格が出ない事象の救済。
  9053. \t\t\t\t// pm/幅/奥行/高さ は従来どおり一致を要求するため通常商品の価格選択に影響しない。
  9054. \t\t\t\tif (candidates.length === 0) {
  9055. \t\t\t\t    candidates = pp.filter(function(el){
  9056. \t\t\t\t        return axisMatch(pw, el.w) && axisMatch(pd, el.d) && axisMatch(ph, el.h) && axisMatch(pm, el.m);
  9057. \t\t\t\t    });
  9058. \t\t\t\t}
  9059. \t\t\t\tvar picked = null;
  9060. \t\t\t\t// 優先 1: 色も含めて完全一致 (\"色1/色2\" 形式の split match を含む)
  9061. \t\t\t\tfor (var ii = 0; ii < candidates.length; ii++) {
  9062. \t\t\t\t    if (colorMatch(pc, candidates[ii].c)) { picked = candidates[ii]; break; }
  9063. \t\t\t\t}
  9064. \t\t\t\t// 優先 2: 完全一致なし & user の pc が候補のどの c 値にも該当しない (= 命名違い等)
  9065. \t\t\t\t//   かつ候補全行で price が一致する場合は、色軸を実質無視して先頭行を採用.
  9066. \t\t\t\t//   例 id=3353: pp.c は \"ステンカラー+...\" 6種だが price は全て同じなので
  9067. \t\t\t\t//     SM(スミ) を選んでも安全に最初の行の価格を返せる.
  9068. \t\t\t\tif (!picked && candidates.length > 0) {
  9069. \t\t\t\t    var ppCsInCand = candidates.map(function(r){ return r.c || ''; });
  9070. \t\t\t\t    var pcAbsent = (pc !== '' && pc !== '指定なし' && ppCsInCand.indexOf(pc) === -1
  9071. \t\t\t\t                    && ppCsInCand.every(function(v){ return v.indexOf('/') === -1 || v.split('/').map(function(s){return s.trim();}).indexOf(pc) === -1; }));
  9072. \t\t\t\t    if (pcAbsent) {
  9073. \t\t\t\t        var uniqPrices = new Set();
  9074. \t\t\t\t        candidates.forEach(function(r){ uniqPrices.add(String(r.price)); });
  9075. \t\t\t\t        if (uniqPrices.size === 1) {
  9076. \t\t\t\t            // 全候補同価格 → 色軸を wildcard 扱いで OK
  9077. \t\t\t\t            picked = candidates[0];
  9078. \t\t\t\t        }
  9079. \t\t\t\t        // 価格が異なる場合は意図的に picked=null のまま「対応しておりません」.
  9080. \t\t\t\t    }
  9081. \t\t\t\t}
  9082. \t\t\t\tpp.forEach((el) => {
  9083. \t\t\t\t  if (el === picked) {
  9084. \t\t\t\t\tpp_matched = true;
  9085. \t\t\t\t\t// tg block-keyed オプション差額を集計 (tg 以外は total=0)
  9086. \t\t\t\t\tvar oiCalc = collectOptionItems(el.w || '', el.d || '');
  9087. \t\t\t\t\t// tg ブロックに合わせてラジオを再描画 (tg 以外は no-op)
  9088. \t\t\t\t\trenderOptionItemRadios(el.w || '', el.d || '');
  9089. \t\t\t\t\t// fe ブロックの種類×段数 サブ radio (fe 以外/未設定は no-op)
  9090. \t\t\t\t\trenderFeBlockRadios();
  9091. \t\t\t\t\t// fe ご希望のフェンス設置方法 — 「既存ブロックに穴空け」 entry の連動表示
  9092. \t\t\t\t\tupdateFeOpConditionalVisibility();
  9093. \t\t\t\t\tvar calc       = calcGoukei(el, opCalc.total, ctx);
  9094. \t\t\t\t\tvar goukei     = calc.goukei;
  9095. \t\t\t\t\tvar price      = calc.price;
  9096. \t\t\t\t\tvar ct         = calc.ct;
  9097. \t\t\t\t\tvar optionSum  = calc.opt;
  9098. \t\t\t\t\t// tf(人工芝): 必要枚数入力へ算出結果を反映(施工サイズ入力時は上書き、
  9099. \t\t\t\t\t// 直接指定時は同値なので実質変化なし。要素が無い sale_type では no-op)
  9100. \t\t\t\t\tvar \$tfQty = \$('#tf_qty');
  9101. \t\t\t\t\tif (\$tfQty.length) \$tfQty.val(calc.qty || 1);
  9102. \t\t\t\t\t// オプション差額は税抜 → 税込に変換して合計に加算
  9103. \t\t\t\t\tvar oiIncTax   = toIncTax(oiCalc.total);
  9104. \t\t\t\t\tgoukei += oiIncTax;
  9105. \t\t\t\t\tprice  += oiIncTax;  // 差額は本体価格扱いとして mitsumori_price にも加算
  9106. \t\t\t\t\t// maker_price も scraper が税抜で保存しているため税込に変換
  9107. \t\t\t\tvar makerPrice = toIncTax(parseInt(el.maker_price) || 0);
  9108. \t\t\t\t\t\$('#mitsumori_message').text(formatter.format(goukei) + \"円\");
  9109. \t\t\t\t\t\$('#mitsumori_goukei').text(formatter.format(goukei) + \"円\");
  9110. \t\t\t\t\t\$('#mitsumori_off').text(formatter.format(price - makerPrice) + \"円\");
  9111. \t\t\t\t\t\$('#mitsumori_price').text(formatter.format(price) + \"円\");
  9112. \t\t\t\t\t\$('#maker_price').text(formatter.format(makerPrice) + \"円\");
  9113. \t\t\t\t\t\$('#mitsumori_ct').text(formatter.format(ct) + \"円\");
  9114. \t\t\t\t\t\$('#mitsumori_option').text(formatter.format(optionSum) + \"円\");
  9115. \t\t\t\t\t\$('#mitsumori_kei').text(formatter.format(goukei) + \"円\");
  9116. \t\t\t\t\t\$('#mitsumori_price_01').text(formatter.format(price) + \"円\");
  9117. \t\t\t\t\t\$('#mitsumori_price_02').text(formatter.format(price) + \"円\");
  9118. \t\t\t\t\t\$('#mitsumori_ct_01').text(formatter.format(ct) + \"円\");
  9119. \t\t\t\t\t\$('#mitsumori_ct_02').text(formatter.format(ct) + \"円\");
  9120. \t\t\t\t\t\$('#mitsumori_goukei_02').text(formatter.format(goukei) + \"円\");
  9121. \t\t\t\t\tvar shoukei = goukei / 1.1;
  9122. \t\t\t\t\tvar tax     = parseInt(goukei - shoukei);
  9123. \t\t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(parseInt(shoukei)) + \"円\");
  9124. \t\t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + \"円\");
  9125. \t\t\t\t\t// PDF 明細用:オプション内訳テーブルを差し込む (施工オプション + tg block オプション)
  9126. \t\t\t\t\trenderOptionDetailRows(opCalc.items.concat(oiCalc.items.map(function(it){
  9127. \t\t\t\t\t\treturn { name: it.name, value: it.label, price: it.diff };
  9128. \t\t\t\t\t})));
  9129. \t\t\t\t  }
  9130. \t\t\t\t});
  9131. \t\t\t\tif (!pp_matched) {
  9132. \t\t\t\t\t\$('#mitsumori_message').text(\"この組み合わせは対応しておりません\");
  9133. \t\t\t\t\t\$('#mitsumori_btn').hide();
  9134. \t\t\t\t\t\$('#mitsumori_goukei').text(\"---円\");
  9135. \t\t\t\t\t\$('#mitsumori_off').text(\"---円\");
  9136. \t\t\t\t\t\$('#mitsumori_price').text(\"---円\");
  9137. \t\t\t\t\t\$('#maker_price').text(\"---円\");
  9138. \t\t\t\t\t\$('#mitsumori_ct').text(\"---円\");
  9139. \t\t\t\t\t\$('#mitsumori_option').text(\"---円\");
  9140. \t\t\t\t\t\$('#mitsumori_kei').text(\"---円\");
  9141. \t\t\t\t\t\$('#mitsumori_shoukei').text(\"---円\");
  9142. \t\t\t\t\t\$('#mitsumori_tax').text(\"---円\");
  9143. \t\t\t\t}
  9144. \t\t\t\t// mitsumori_json: バック側に送信する見積データ
  9145. \t\t\t\tvar mitsumori_json = { \"mitsumori_goukei\": \$('#mitsumori_goukei').text(),
  9146. \t\t\t\t\t\t\t\t\t\t\"mitsumori_goukei_02\": \$('#mitsumori_goukei_02').text(),
  9147. \t\t\t\t\t\t\t\t\t\t\"mitsumori_price\": \$('#mitsumori_price').text(),
  9148. \t\t\t\t\t\t\t\t\t\t\"maker_price\": \$('#maker_price').text(),
  9149. \t\t\t\t\t\t\t\t\t\t\"mitsumori_off\": \$('#mitsumori_off').text(),
  9150. \t\t\t\t\t\t\t\t\t\t\"mitsumori_ct\": \$('#mitsumori_ct').text(),
  9151. \t\t\t\t\t\t\t\t\t\t\"mitsumori_option\": \$('#mitsumori_option').text(),
  9152. \t\t\t\t\t\t\t\t\t\t\"product_id\": {{ Product.id }},
  9153. \t\t\t\t\t\t\t\t\t\t\"sale_type\": SALE_TYPE_ID,
  9154. \t\t\t\t\t\t\t\t\t\t\"pw\": pw,
  9155. \t\t\t\t\t\t\t\t\t\t\"pd\": pd,
  9156. \t\t\t\t\t\t\t\t\t\t\"ph\": ph,
  9157. \t\t\t\t\t\t\t\t\t\t\"pm\": pm,
  9158. \t\t\t\t\t\t\t\t\t\t\"pc\": pc,
  9159. \t\t\t\t\t\t\t\t\t\t\"op\": [op0,op1,op2,op3,op4,op5,op6,op7,op8,op9,op10],
  9160. \t\t\t\t\t\t\t\t\t\t\"op_items\": opCalc.items,
  9161. \t\t\t\t\t\t\t\t\t\t\"mado_w\":     ctx.mado_w,
  9162. \t\t\t\t\t\t\t\t\t\t\"mado_h\":     ctx.mado_h,
  9163. \t\t\t\t\t\t\t\t\t\t\"mado_type\":  ctx.mado_type,
  9164. \t\t\t\t\t\t\t\t\t\t\"glass_type\": ctx.glass_type,
  9165. \t\t\t\t\t\t\t\t\t\t\"set_count\":  ctx.set_count,
  9166. \t\t\t\t\t\t\t\t\t\t\"daisu\":      ctx.daisu,
  9167. \t\t\t\t\t\t\t\t\t\t\"maisu\":      ctx.maisu,
  9168. \t\t\t\t\t\t\t\t\t\t\"suuryou\":    ctx.suuryou,
  9169. \t\t\t\t\t\t\t\t\t\t\"area\":       ctx.area,
  9170. \t\t\t\t\t\t\t\t\t\t\"tf_len\":     ctx.tf_len,
  9171. \t\t\t\t\t\t\t\t\t\t\"tf_wid\":     ctx.tf_wid,
  9172. \t\t\t\t\t\t\t\t\t\t\"tf_qty\":     \$('#tf_qty').val(),
  9173. \t\t\t\t\t\t\t\t\t\t\"deck_step\":  ctx.deck_step,
  9174. \t\t\t\t\t\t\t\t\t\t\"deck_fence\": ctx.deck_fence };
  9175. \t\t\t\t\$('#mitsumori_json').val(JSON.stringify(mitsumori_json));
  9176. \t\t\t}
  9177. \t\t}
  9178. \t\t// PDF/モーダル明細の動的差し替え(基本工事費の次にオプション行を追加)
  9179. \t\tfunction renderOptionDetailRows(items) {
  9180. \t\t\tvar \$tbody = \$('.modal-mitsumori table tbody');
  9181. \t\t\tif (!\$tbody.length) return;
  9182. \t\t\t\$tbody.find('tr.opt-row').remove();
  9183. \t\t\tvar anchorRow = \$tbody.find('tr').filter(function(){
  9184. \t\t\t\treturn \$(this).find('td:first').text().indexOf('残土') !== -1
  9185. \t\t\t\t\t|| \$(this).find('td:first').text().indexOf('基本工事費') !== -1;
  9186. \t\t\t}).last();
  9187. \t\t\titems.forEach(function(it){
  9188. \t\t\t\tif (!it.name || !it.value) return;
  9189. \t\t\t\tvar priceTxt = it.price > 0
  9190. \t\t\t\t\t? formatter.format(it.price) + '円'
  9191. \t\t\t\t\t: '0円';
  9192. \t\t\t\tvar \$tr = \$('<tr class=\"opt-row\"></tr>')
  9193. \t\t\t\t\t.append('<td>' + it.name + ':' + it.value + '</td>')
  9194. \t\t\t\t\t.append('<td>1</td>')
  9195. \t\t\t\t\t.append('<td>式</td>')
  9196. \t\t\t\t\t.append('<td>' + priceTxt + '</td>')
  9197. \t\t\t\t\t.append('<td>' + (it.price > 0 ? formatter.format(it.price) + '円' : '') + '</td>');
  9198. \t\t\t\tif (anchorRow.length) {
  9199. \t\t\t\t\tanchorRow.after(\$tr);
  9200. \t\t\t\t\tanchorRow = \$tr;
  9201. \t\t\t\t} else {
  9202. \t\t\t\t\t\$tbody.append(\$tr);
  9203. \t\t\t\t}
  9204. \t\t\t});
  9205. \t\t}
  9206. \t\t// 見積書モーダルを開く直前に、右側「現在のお見積り額」パネルの表示値を
  9207. \t\t// モーダル内の対応 ID にコピーして金額の食い違いを防ぐ。
  9208. \t\t// pw/pd/ph/pm が未選択で mitsumori_simulation の full update に到達しない場合でも、
  9209. \t\t// パネル側の値(HTML 静的初期値 or 直近の simulation 結果)が modal にも反映される。
  9210. \t\tfunction syncMitsumoriModalFromPanel() {
  9211. \t\t\tvar goukeiText = \$('#mitsumori_goukei').text();
  9212. \t\t\tvar priceText  = \$('#mitsumori_price').text();
  9213. \t\t\tvar ctText     = \$('#mitsumori_ct').text();
  9214. \t\t\t\$('#mitsumori_kei').text(goukeiText);
  9215. \t\t\t\$('#mitsumori_price_01').text(priceText);
  9216. \t\t\t\$('#mitsumori_price_02').text(priceText);
  9217. \t\t\t\$('#mitsumori_ct_01').text(ctText);
  9218. \t\t\t\$('#mitsumori_ct_02').text(ctText);
  9219. \t\t\t\$('#mitsumori_goukei_02').text(goukeiText);
  9220. \t\t\t// 小計 / 消費税 は税込 goukei から逆算
  9221. \t\t\tvar num = parseInt(goukeiText.replace(/[^\\d-]/g, ''), 10);
  9222. \t\t\tif (!isNaN(num) && num > 0) {
  9223. \t\t\t\tvar shoukei = Math.round(num / 1.1);
  9224. \t\t\t\tvar tax     = num - shoukei;
  9225. \t\t\t\t\$('#mitsumori_shoukei').text(formatter.format(shoukei) + '円');
  9226. \t\t\t\t\$('#mitsumori_tax').text(formatter.format(tax) + '円');
  9227. \t\t\t} else {
  9228. \t\t\t\t\$('#mitsumori_shoukei').text('---円');
  9229. \t\t\t\t\$('#mitsumori_tax').text('---円');
  9230. \t\t\t}
  9231. \t\t}
  9232. \t\t\$(document).on('show.bs.modal', '#modal-mitsumori', function () {
  9233. \t\t\tsyncMitsumoriModalFromPanel();
  9234. \t\t});
  9235.         {# pc の auto-init: pw/pd/ph/pm と同じく p_c(matrix 派生)の length==1 or 全空で「指定なし」化.
  9236.            search_word(color) が空の「複合色」型商品で pc が空のまま放置されて
  9237.            「カラーを選択してください」固定になるバグの修正.
  9238.            search_word に登録された name があれば優先採用. #}
  9239.         {% if p_c and (p_c|length == 1 or p_c|join == \"\") %}
  9240.             pc = \"指定なし\";
  9241.             {% for pc_val in p_c %}{% if pc_val %} pc = \"{{ pc_val }}\"; {% endif %}{% endfor %}
  9242.             {% if color and color|length == 1 %}
  9243.                 {% for cc in color %}{% if cc and cc['name'] %} pc = \"{{ cc['name'] }}\"; {% endif %}{% endfor %}
  9244.             {% endif %}
  9245.         {% elseif color and color|length == 1 %}
  9246.             pc = \"指定なし\";
  9247. \t\t\t{% for cc in color %}{% if cc and cc['name'] %} pc = \"{{ cc['name'] }}\"; {% endif %}{% endfor %}
  9248. \t\t{% endif %}
  9249.         {% if p_w and (p_w|length == 1 or p_w|join == \"\") %}
  9250.             pw = \"指定なし\";
  9251. \t\t\t{% for pw in p_w %}{% if pw %} pw = \"{{ pw }}\"; {% endif %}{% endfor %}
  9252. \t\t{% endif %}
  9253.         {% if p_d and (p_d|length == 1 or p_d|join == \"\") %}
  9254.             pd = \"指定なし\";
  9255. \t\t\t{% for pd in p_d %}{% if pd %} pd = \"{{ pd }}\"; {% endif %}{% endfor %}
  9256. \t\t{% endif %}
  9257.         {% if p_h and (p_h|length == 1 or p_h|join == \"\") %}
  9258.             ph = \"指定なし\";
  9259. \t\t\t{% for ph in p_h %}{% if ph %} ph = \"{{ ph }}\"; {% endif %}{% endfor %}
  9260. \t\t{% endif %}
  9261.         {% if p_m and (p_m|length == 1 or p_m|join == \"\") %}
  9262.             pm = \"指定なし\";
  9263. \t\t\t{% for pm in p_m %}{% if pm %} pm = \"{{ pm }}\"; {% endif %}{% endfor %}
  9264. \t\t{% endif %}
  9265.         {# p_option1 / p_option2 の auto-init: length==1 or 全空で JS 変数を埋める #}
  9266.         {% if p_option1 and (p_option1|length == 1 or p_option1|join == \"\") %}
  9267.             option1 = \"\";
  9268. \t\t\t{% for opt1 in p_option1 %}{% if opt1 %} option1 = \"{{ opt1|e('js') }}\"; {% endif %}{% endfor %}
  9269. \t\t{% endif %}
  9270.         {% if p_option2 and (p_option2|length == 1 or p_option2|join == \"\") %}
  9271.             option2 = \"\";
  9272. \t\t\t{% for opt2 in p_option2 %}{% if opt2 %} option2 = \"{{ opt2|e('js') }}\"; {% endif %}{% endfor %}
  9273. \t\t{% endif %}
  9274. \t\t// カラー radio が複数あるとき初期チェックが無いと「カラーを選択してください」固定になるので、
  9275. \t\t// 何もチェックされていなければ「最初の radio」を選択する。
  9276. \t\t// sale_type≠3 は name=\"color\", sale_type=3 は name=\"color3\".
  9277. \t\t//
  9278. \t\t// 注意:
  9279. \t\t//   ・search_word(= radio の値)と pp.c(= matrix の色軸)は別の命名体系のケースがある
  9280. \t\t//     (例 id=3353: radio=\"SM(スミ)\" / pp.c=\"ステンカラー+セピアブラウン\")
  9281. \t\t//   ・pp.c に合わせて radio を選ぼうとしても文字列一致しないので無意味。
  9282. \t\t//   ・単純に「先頭の radio」を選ぶ実装に戻し、マッチング側で命名体系違いを吸収する
  9283. \t\t//     (pc が pp.c のどの値にもマッチしないときは色軸を wildcard 扱いにする)。
  9284. \t\t//   ・.rp-section-label のテキストも忘れずに同期する(古い session 値が残ると
  9285. \t\t//     \"ステンカラー+セピアブラウン\" のような表示と実際の radio が食い違う)。
  9286. \t\t(function autoSelectFirstColor(){
  9287. \t\t\tvar groups = ['color', 'color3'];
  9288. \t\t\tfor (var gi = 0; gi < groups.length; gi++) {
  9289. \t\t\t\tvar name = groups[gi];
  9290. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + name + '\"]');
  9291. \t\t\t\tif (nodes.length === 0) continue;
  9292. \t\t\t\tvar anyChecked = false;
  9293. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  9294. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  9295. \t\t\t\t}
  9296. \t\t\t\tif (anyChecked) continue;
  9297. \t\t\t\tvar target = nodes[0];
  9298. \t\t\t\ttarget.checked = true;
  9299. \t\t\t\tpc = target.value;
  9300. \t\t\t\t// opt-btn の is-selected を付け替え
  9301. \t\t\t\tvar lbl = target.closest('.opt-btn');
  9302. \t\t\t\tif (lbl) {
  9303. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  9304. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  9305. \t\t\t\t\tlbl.classList.add('is-selected');
  9306. \t\t\t\t}
  9307. \t\t\t\t// 「カラー: <name>」表示の同期(古い mitsumori_json.pc が残らないように)
  9308. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  9309. \t\t\t\tif (grp) {
  9310. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  9311. \t\t\t\t\tif (section) {
  9312. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  9313. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  9314. \t\t\t\t\t}
  9315. \t\t\t\t}
  9316. \t\t\t}
  9317. \t\t})();
  9318. \t\t// option1 / option2 / pw / pd / ph / pm (matrix 軸の radio 群) も同様に
  9319. \t\t// 「どれもチェックされていなければ先頭を選ぶ」を適用する.
  9320. \t\t//   sale_type=2 の窓タイプ等で「初期表示時に一番初めの選択肢が選択されていない」事象を解消.
  9321. \t\t(function autoSelectFirstMatrixAxis(){
  9322. \t\t\tvar axes = [
  9323. \t\t\t\t{ name: 'pw',      jsVar: 'pw' },
  9324. \t\t\t\t{ name: 'pd',      jsVar: 'pd' },
  9325. \t\t\t\t{ name: 'ph',      jsVar: 'ph' },
  9326. \t\t\t\t{ name: 'pm',      jsVar: 'pm' },
  9327. \t\t\t\t{ name: 'glass_type', jsVar: 'pm' },
  9328. \t\t\t\t{ name: 'option1', jsVar: 'option1' },
  9329. \t\t\t\t{ name: 'option2', jsVar: 'option2' }
  9330. \t\t\t];
  9331. \t\t\tfor (var ai = 0; ai < axes.length; ai++) {
  9332. \t\t\t\tvar ax = axes[ai];
  9333. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"' + ax.name + '\"]');
  9334. \t\t\t\tif (nodes.length === 0) continue;
  9335. \t\t\t\tvar anyChecked = false;
  9336. \t\t\t\tfor (var i = 0; i < nodes.length; i++) {
  9337. \t\t\t\t\tif (nodes[i].checked) { anyChecked = true; break; }
  9338. \t\t\t\t}
  9339. \t\t\t\tif (anyChecked) continue;
  9340. \t\t\t\tvar target = nodes[0];
  9341. \t\t\t\ttarget.checked = true;
  9342. \t\t\t\t// グローバル JS 変数も埋める
  9343. \t\t\t\tif (ax.jsVar === 'pw') pw = target.value;
  9344. \t\t\t\telse if (ax.jsVar === 'pd') pd = target.value;
  9345. \t\t\t\telse if (ax.jsVar === 'ph') ph = target.value;
  9346. \t\t\t\telse if (ax.jsVar === 'pm') pm = target.value;
  9347. \t\t\t\telse if (ax.jsVar === 'option1') option1 = target.value;
  9348. \t\t\t\telse if (ax.jsVar === 'option2') option2 = target.value;
  9349. \t\t\t\tvar lbl = target.closest('.opt-btn');
  9350. \t\t\t\tif (lbl) {
  9351. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  9352. \t\t\t\t\tfor (var k = 0; k < sib.length; k++) sib[k].classList.remove('is-selected');
  9353. \t\t\t\t\tlbl.classList.add('is-selected');
  9354. \t\t\t\t}
  9355. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || (target.closest('.form-group'));
  9356. \t\t\t\tif (grp) {
  9357. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  9358. \t\t\t\t\tif (section) {
  9359. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  9360. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + target.value + '</span>';
  9361. \t\t\t\t\t}
  9362. \t\t\t\t}
  9363. \t\t\t}
  9364. \t\t})();
  9365. \t\t// 取付/設置工事トグル(off 値が「商品購入のみ」のオプション)は、新規アクセス時に
  9366. \t\t// どちらの radio も未チェックのため初期価格が「商品購入のみ」= 基本工事費抜きになる。
  9367. \t\t// 顧客要望(#10)に合わせ、未選択時は「工事も希望する」(on 側) を初期選択し、
  9368. \t\t// 初期表示を基本工事費込みの最安値に統一する(色・寸法軸の先頭自動選択と同型)。
  9369. \t\t//   ・判定キーは calcGoukei / applyPurchaseOnlyUI と同じ定数「商品購入のみ」。
  9370. \t\t//   ・別用途で op{n} を流用する商品(ウッドデッキ deck_step 等)は radio 値に
  9371. \t\t//     「商品購入のみ」を含まないため対象外(既存挙動を壊さない)。
  9372. \t\t//   ・mitsumori_json 復元やユーザー操作で既に選択済みなら尊重する。
  9373. \t\t(function autoSelectFirstInstall(){
  9374. \t\t\tfor (var i = 0; i <= 10; i++) {
  9375. \t\t\t\tvar nodes = document.querySelectorAll('input[type=\"radio\"][name=\"op' + i + '\"]');
  9376. \t\t\t\tif (nodes.length === 0) continue;
  9377. \t\t\t\t// このグループが「商品購入のみ」を off に持つ工事トグルか判定し、
  9378. \t\t\t\t// 「商品購入のみ」でない側 (= 工事希望 on) を取得する。
  9379. \t\t\t\tvar hasPurchaseOnly = false;
  9380. \t\t\t\tvar onNode = null;
  9381. \t\t\t\tfor (var j = 0; j < nodes.length; j++) {
  9382. \t\t\t\t\tif (nodes[j].value === '商品購入のみ') hasPurchaseOnly = true;
  9383. \t\t\t\t\telse if (!onNode) onNode = nodes[j];
  9384. \t\t\t\t}
  9385. \t\t\t\tif (!hasPurchaseOnly || !onNode) continue;
  9386. \t\t\t\tvar anyChecked = false;
  9387. \t\t\t\tfor (var k = 0; k < nodes.length; k++) {
  9388. \t\t\t\t\tif (nodes[k].checked) { anyChecked = true; break; }
  9389. \t\t\t\t}
  9390. \t\t\t\tif (anyChecked) continue;
  9391. \t\t\t\tonNode.checked = true;
  9392. \t\t\t\t// グローバル op 変数を on 値で埋める(calcGoukei の purchaseOnly 判定が参照)
  9393. \t\t\t\tswitch (i) {
  9394. \t\t\t\t\tcase 0:  op0  = onNode.value; break;
  9395. \t\t\t\t\tcase 1:  op1  = onNode.value; break;
  9396. \t\t\t\t\tcase 2:  op2  = onNode.value; break;
  9397. \t\t\t\t\tcase 3:  op3  = onNode.value; break;
  9398. \t\t\t\t\tcase 4:  op4  = onNode.value; break;
  9399. \t\t\t\t\tcase 5:  op5  = onNode.value; break;
  9400. \t\t\t\t\tcase 6:  op6  = onNode.value; break;
  9401. \t\t\t\t\tcase 7:  op7  = onNode.value; break;
  9402. \t\t\t\t\tcase 8:  op8  = onNode.value; break;
  9403. \t\t\t\t\tcase 9:  op9  = onNode.value; break;
  9404. \t\t\t\t\tcase 10: op10 = onNode.value; break;
  9405. \t\t\t\t}
  9406. \t\t\t\t// opt-btn の is-selected を付け替え
  9407. \t\t\t\tvar lbl = onNode.closest('.opt-btn');
  9408. \t\t\t\tif (lbl) {
  9409. \t\t\t\t\tvar sib = lbl.parentNode ? lbl.parentNode.querySelectorAll('.opt-btn') : [];
  9410. \t\t\t\t\tfor (var s = 0; s < sib.length; s++) sib[s].classList.remove('is-selected');
  9411. \t\t\t\t\tlbl.classList.add('is-selected');
  9412. \t\t\t\t}
  9413. \t\t\t\t// rp-section-label 表示同期 + 現地調査文言(is_removal_unknown / is_tf_kouji)を on 表示に
  9414. \t\t\t\tvar grp = (lbl && lbl.closest('.form-group')) || onNode.closest('.form-group');
  9415. \t\t\t\tif (grp) {
  9416. \t\t\t\t\tvar section = grp.querySelector('.rp-section-label');
  9417. \t\t\t\t\tif (section) {
  9418. \t\t\t\t\t\tvar labelHead = section.textContent.split(':')[0].trim();
  9419. \t\t\t\t\t\tsection.innerHTML = labelHead + ': <span>' + onNode.value + '</span>';
  9420. \t\t\t\t\t}
  9421. \t\t\t\t\tvar note = grp.querySelector('.opt-survey-note[data-op-idx=\"' + i + '\"]');
  9422. \t\t\t\t\tif (note) note.style.display = '';
  9423. \t\t\t\t}
  9424. \t\t\t}
  9425. \t\t})();
  9426. \t\t// ページ読み込み時: 見積金額が「合計」になっているため、カート数量は基本1
  9427. \t\t// sale_type=9(商品のみ購入)だけ通常 EC として数量を引き継ぐ
  9428. \t\t(function initQuantityByType(){
  9429. \t\t\tvar saleType = {{ ProductClass.SaleType.id }};
  9430. \t\t\tif (saleType == 9 && \$('#quantity_only').length) {
  9431. \t\t\t\t\$('#quantity').val(parseInt(\$('#quantity_only').val()) || 1);
  9432. \t\t\t} else {
  9433. \t\t\t\t\$('#quantity').val(1);
  9434. \t\t\t\t\$('input[name=\"quantity\"]').val(1);
  9435. \t\t\t}
  9436. \t\t})();
  9437. \t\t// type → ラベルのプレフィックス文字列
  9438. \t\t// option1/option2 のラベルは category 依存 (rd: ランマ/タイプ, sh: サイズプリセット/駆動方式 等).
  9439. \t\t// PHP から渡された option1_label / option2_label を埋め込み、JS 側でラベル更新に使う.
  9440. \t\tvar optLabelMap = {pc:'カラー', pw:'幅', pd:'奥行き', ph:'高さ', pm:'素材',
  9441. \t\t                   option1: '{{ option1_label|default('オプション1')|e('js') }}',
  9442. \t\t                   option2: '{{ option2_label|default('オプション2')|e('js') }}'};
  9443. \t\t// type → input[name]
  9444. \t\tvar optNameMap  = {pc:'color', pw:'pw', pd:'pd', ph:'ph', pm:'pm',
  9445. \t\t                   option1: 'option1', option2: 'option2'};
  9446. \t\t// opt-btn用: 値を直接受け取るラッパー
  9447. \t\tfunction mitsumori_simulation_val(type, value) {
  9448. \t\t\tif (type === 'pc') pc = value;
  9449. \t\t\tif (type === 'pw') pw = value;
  9450. \t\t\tif (type === 'pd') pd = value;
  9451. \t\t\tif (type === 'ph') ph = value;
  9452. \t\t\tif (type === 'pm') pm = value;
  9453. \t\t\tif (type === 'option1') option1 = value;
  9454. \t\t\tif (type === 'option2') option2 = value;
  9455. \t\t\t// is-selected クラスを同グループ内で付け替え
  9456. \t\t\tvar inputName = optNameMap[type];
  9457. \t\t\tif (inputName) {
  9458. \t\t\t\tvar \$btns = \$('input[name=\"' + inputName + '\"]').closest('.opt-btn');
  9459. \t\t\t\t\$btns.removeClass('is-selected');
  9460. \t\t\t\t\$btns.filter(function(){
  9461. \t\t\t\t\treturn \$(this).find('input').val() === value;
  9462. \t\t\t\t}).addClass('is-selected');
  9463. \t\t\t}
  9464. \t\t\t// ラベル行の選択値テキストを更新(例: 「カラー: ブラック」)
  9465. \t\t\tvar labelPrefix = optLabelMap[type];
  9466. \t\t\tif (labelPrefix) {
  9467. \t\t\t\t// 対象のrp-section-labelを特定(input[name]を含む親を遡る)
  9468. \t\t\t\tvar \$group = \$('input[name=\"' + inputName + '\"]').first().closest('.form-group');
  9469. \t\t\t\tvar \$label = \$group.find('.rp-section-label');
  9470. \t\t\t\t\$label.html(labelPrefix + ': <span>' + value + '</span>');
  9471. \t\t\t}
  9472. \t\t\t// simulation本体を呼ぶ(value_idは空でOK、グローバル変数を使う)
  9473. \t\t\tmitsumori_simulation('', '');
  9474. \t\t}
  9475. \t\tmitsumori_simulation(\"\",\"\");
  9476. \t\t// ボタン群: 親幅を超える、または3行以上になる場合は is-scroll を付与し
  9477. \t\t// 縦3段グリッド+横スクロール表示にする(顧客要望「3列くらいで横スクロール」)
  9478. \t\tfunction applyBtnGroupScroll() {
  9479. \t\t\t\$('.rp-btn-group, .opt-btn-group').each(function() {
  9480. \t\t\t\tvar \$group = \$(this);
  9481. \t\t\t\t\$group.removeClass('is-scroll');
  9482. \t\t\t\tvar \$items = \$group.children();
  9483. \t\t\t\tif (\$items.length === 0) return;
  9484. \t\t\t\tvar parentWidth = \$group.parent().width() || \$group.width();
  9485. \t\t\t\tvar totalWidth = 0;
  9486. \t\t\t\tvar gap = parseInt(\$group.css('gap'), 10) || 8;
  9487. \t\t\t\t\$items.each(function() {
  9488. \t\t\t\t\ttotalWidth += this.offsetWidth + gap;
  9489. \t\t\t\t});
  9490. \t\t\t\t// 単一ボタンが親幅を超える、もしくは合計幅が親幅を超える → 横スクロール化
  9491. \t\t\t\tvar anyTooWide = false;
  9492. \t\t\t\t\$items.each(function() {
  9493. \t\t\t\t\tif (this.offsetWidth > parentWidth) { anyTooWide = true; return false; }
  9494. \t\t\t\t});
  9495. \t\t\t\t// 折り返し時の行数も計測
  9496. \t\t\t\tvar tops = {};
  9497. \t\t\t\t\$items.each(function() { tops[this.offsetTop] = true; });
  9498. \t\t\t\tvar rowCount = Object.keys(tops).length;
  9499. \t\t\t\tif (anyTooWide || totalWidth > parentWidth * 2 || rowCount >= 3) {
  9500. \t\t\t\t\t\$group.addClass('is-scroll');
  9501. \t\t\t\t}
  9502. \t\t\t});
  9503. \t\t}
  9504. \t\tapplyBtnGroupScroll();
  9505. \t\t\$(window).on('resize', function() {
  9506. \t\t\tclearTimeout(window._btnScrollTimer);
  9507. \t\t\twindow._btnScrollTimer = setTimeout(applyBtnGroupScroll, 150);
  9508. \t\t});
  9509. \t\t// onload: 見積金額が確定している場合は「工事費込み価格」表示を一致させる
  9510. \t\t(function syncPrice02Display() {
  9511. \t\t\tvar goukeiEl = document.getElementById('mitsumori_goukei');
  9512. \t\t\tvar displayEl = document.getElementById('price02-display');
  9513. \t\t\tif (!goukeiEl || !displayEl) return;
  9514. \t\t\tvar goukeiText = goukeiEl.textContent.trim();
  9515. \t\t\t// ---円(未確定)の場合は書き換えない
  9516. \t\t\tif (goukeiText && goukeiText !== '---円') {
  9517. \t\t\t\tdisplayEl.textContent = goukeiText;
  9518. \t\t\t}
  9519. \t\t\t// 以降の変更にも追従: mitsumori_goukei を監視
  9520. \t\t\tnew MutationObserver(function() {
  9521. \t\t\t\tvar text = goukeiEl.textContent.trim();
  9522. \t\t\t\tif (text && text !== '---円') {
  9523. \t\t\t\t\tdisplayEl.textContent = text;
  9524. \t\t\t\t}
  9525. \t\t\t}).observe(goukeiEl, { childList: true, subtree: true, characterData: true });
  9526. \t\t})();
  9527. \t\tfunction contact_form(product_id){
  9528. \t\t\t\$('#form1').attr('action', '{{ url('contact', {product:Product.id}) }}');
  9529. \t\t\t\$('#form1').submit();
  9530. \t\t}
  9531. \t\t// maisu / madoset は下部の新しい関数定義を使用
  9532. \t\tfunction heibei(bei){
  9533. \t\t\t\$('#heibei').val(parseInt(\$('#heibei').val()) + bei);
  9534. \t\t\tif(parseInt(\$('#heibei').val()) < 1){ \$('#heibei').val(1); }
  9535. \t\t\tif(parseInt(\$('#heibei').val()) > 100){ \$('#heibei').val(100); }
  9536. \t\t\t// goukei に既に枚数を含むため、カート数量は1で固定
  9537. \t\t\t\$('#quantity').val(1);
  9538. \t\t\tmitsumori_simulation('heibei','heibei');
  9539. \t\t}
  9540. \t\tfunction daisu(dai){
  9541. \t\t\t\$('#daisu').val(parseInt(\$('#daisu').val()) + dai);
  9542. \t\t\tif(parseInt(\$('#daisu').val()) < 1){ \$('#daisu').val(1); }
  9543. \t\t\tif(parseInt(\$('#daisu').val()) > 10){ \$('#daisu').val(10); }
  9544. \t\t\t\$('#quantity').val(1);
  9545. \t\t\tmitsumori_simulation('daisu','daisu');
  9546. \t\t}
  9547. \t\t// sale_type=7(数量買い・基本工事費固定)用:個数入力
  9548. \t\tfunction suuryou(n){
  9549. \t\t\t\$('#suuryou').val(parseInt(\$('#suuryou').val()) + n);
  9550. \t\t\tif(parseInt(\$('#suuryou').val()) < 1){ \$('#suuryou').val(1); }
  9551. \t\t\tif(parseInt(\$('#suuryou').val()) > 100){ \$('#suuryou').val(100); }
  9552. \t\t\t\$('#quantity').val(1);
  9553. \t\t\tmitsumori_simulation('suuryou','suuryou');
  9554. \t\t}
  9555. \t\tfunction maisu(mai){
  9556. \t\t\t\$('#maisu').val(parseInt(\$('#maisu').val()) + mai);
  9557. \t\t\t// sale_type=4 (フェンス) は3枚未満不可、6 (芝生) は1枚から
  9558. \t\t\tvar minMai = (SALE_TYPE_ID == 4) ? 3 : 1;
  9559. \t\t\tif(parseInt(\$('#maisu').val()) < minMai){ \$('#maisu').val(minMai); }
  9560. \t\t\tif(parseInt(\$('#maisu').val()) > 100){ \$('#maisu').val(100); }
  9561. \t\t\t\$('#quantity').val(1);
  9562. \t\t\tmitsumori_simulation('maisu','maisu');
  9563. \t\t}
  9564. \t\t// タイプ2: セット数プルダウン連動
  9565. \t\tfunction madosetSelect(val){
  9566. \t\t\tvar v = parseInt(val);
  9567. \t\t\tif(v < 1) v = 1;
  9568. \t\t\tif(v > 20) v = 20;
  9569. \t\t\t\$('#set_count').val(v);
  9570. \t\t\t\$('#quantity').val(1);
  9571. \t\t\t\$('input[name=\"quantity\"]').val(1);
  9572. \t\t\tmitsumori_simulation('set','set_count');
  9573. \t\t}
  9574. \t\t// タイプ2: ±ボタン版(後方互換)
  9575. \t\tfunction madoset(mai){
  9576. \t\t\tvar current = parseInt(\$('#set_count').val()) || 1;
  9577. \t\t\tvar next = current + mai;
  9578. \t\t\tif(next < 1) next = 1;
  9579. \t\t\tif(next > 20) next = 20;
  9580. \t\t\t\$('#set_count').val(next);
  9581. \t\t\tmadosetSelect(next);
  9582. \t\t}
  9583. \t\t// タイプ5: ステップ・フェンス選択値を mitsumori_json に保存するためのグローバル変数
  9584. \t\tvar deck_step = \"{% if mitsumori_json and mitsumori_json.deck_step is defined %}{{ mitsumori_json.deck_step|default('不要') }}{% else %}不要{% endif %}\";
  9585. \t\tvar deck_fence = \"{% if mitsumori_json and mitsumori_json.deck_fence is defined %}{{ mitsumori_json.deck_fence|default('不要') }}{% else %}不要{% endif %}\";
  9586. \t\t// PDF出力: モーダルの mitsumori_json をフォームに同期してから送信
  9587. \t\tfunction syncPdfJson(){
  9588. \t\t\tvar jsonVal = \$('#mitsumori_json').val();
  9589. \t\t\t\$('#pdf_mitsumori_json').val(jsonVal);
  9590. \t\t}
  9591. \t\t// タイプ9: 商品のみ購入
  9592. \t\tfunction quantityOnly(val){
  9593. \t\t\tvar current = parseInt(\$('#quantity_only').val()) || 1;
  9594. \t\t\tvar next = current + val;
  9595. \t\t\tif(next < 1) next = 1;
  9596. \t\t\t\$('#quantity_only').val(next);
  9597. \t\t\t\$('#quantity').val(next);
  9598. \t\t}
  9599.         // ===== スマホ用下部固定バーへの金額同期 =====
  9600.         // mitsumori_message と mitsumori_goukei を監視して下部バーを更新
  9601.         (function() {
  9602.             var msgTarget   = document.getElementById('mitsumori_message');
  9603.             var goukeiTarget = document.getElementById('mitsumori_goukei');
  9604.             var spPrice     = document.getElementById('sp-mitsumori-price');
  9605.             var spBtn       = document.querySelector('#sp-mitsumori-bar .sp-bar__btn');
  9606.             if (!spPrice || !spBtn) return;
  9607.             function syncBar() {
  9608.                 var msg    = msgTarget ? msgTarget.textContent : '';
  9609.                 var goukei = goukeiTarget ? goukeiTarget.textContent : '---円';
  9610.                 // メッセージが「〇〇を選択してください」の場合はメッセージを表示しボタンを非表示
  9611.                 if (msg.indexOf('選択してください') !== -1) {
  9612.                     spPrice.textContent = msg;
  9613.                     spPrice.style.fontSize = '13px';
  9614.                     spPrice.style.color    = '#888';
  9615.                     spBtn.style.display    = 'none';
  9616.                 } else {
  9617.                     // 価格確定時はボタンを表示
  9618.                     spPrice.textContent = goukei;
  9619.                     spPrice.style.fontSize = '18px';
  9620.                     spPrice.style.color    = '#c00';
  9621.                     spBtn.style.display    = 'block';
  9622.                 }
  9623.             }
  9624.             // 初期値を同期
  9625.             syncBar();
  9626.             // mitsumori_message の変化を監視
  9627.             if (msgTarget) {
  9628.                 new MutationObserver(syncBar).observe(
  9629.                     msgTarget, { childList: true, subtree: true, characterData: true }
  9630.                 );
  9631.             }
  9632.             // mitsumori_goukei の変化も監視
  9633.             if (goukeiTarget) {
  9634.                 new MutationObserver(syncBar).observe(
  9635.                     goukeiTarget, { childList: true, subtree: true, characterData: true }
  9636.                 );
  9637.             }
  9638.         })();
  9639.         // ===== 現在のお見積り額: 折りたたみトグルボタンのテキスト切り替え =====
  9640.         (function() {
  9641.             var card = document.querySelector('.mitsumori-card-pc');
  9642.             var btn  = document.querySelector('.btn-mitsumori-toggle .toggle-icon');
  9643.             if (!card || !btn) return;
  9644.             // MutationObserverでcollapsed-cardクラスの変化を監視
  9645.             new MutationObserver(function() {
  9646.                 if (card.classList.contains('collapsed-card')) {
  9647.                     btn.textContent = '▼ 詳細';
  9648.                 } else {
  9649.                     btn.textContent = '▲ 閉じる';
  9650.                 }
  9651.             }).observe(card, { attributes: true, attributeFilter: ['class'] });
  9652.         })();
  9653.         // ===== エリア案内: スマホのみタップで展開 =====
  9654.         (function() {
  9655.             var notice = document.querySelector('.ec-areaNotice');
  9656.             if (!notice) return;
  9657.             notice.addEventListener('click', function(e) {
  9658.                 if (window.innerWidth > 767) return;
  9659.                 // リンククリック時は展開/折りたたみせずリンク遷移
  9660.                 if (e.target.tagName === 'A') return;
  9661.                 notice.classList.toggle('is-open');
  9662.             });
  9663.         })();
  9664.     </script>
  9665.     <script type=\"application/ld+json\">
  9666.     {
  9667.         \"@context\": \"https://schema.org/\",
  9668.         \"@type\": \"Product\",
  9669.         \"name\": \"{{ Product.name }}\",
  9670.         \"image\": [
  9671.             {% for img in Product.ProductImage %}
  9672.                 \"{{ app.request.schemeAndHttpHost }}{{ asset(img, 'save_image') }}\"{% if not loop.last %},{% endif %}
  9673.             {% else %}
  9674.                 \"{{ app.request.schemeAndHttpHost }}{{ asset(''|no_image_product, 'save_image') }}\"
  9675.             {% endfor %}
  9676.         ],
  9677.         \"description\": \"{{ Product.description_list | default(Product.description_detail) | replace({'\\n': '', '\\r': ''}) | slice(0,300) }}\",
  9678.         {% if Product.code_min %}
  9679.         \"sku\": \"{{ Product.code_min }}\",
  9680.         {% endif %}
  9681.         \"offers\": {
  9682.             \"@type\": \"Offer\",
  9683.             \"url\": \"{{ url('product_detail', {'id': Product.id}) }}\",
  9684.             \"priceCurrency\": \"{{ eccube_config.currency }}\",
  9685.             \"price\": {{ Product.getPrice02IncTaxMin ? Product.getPrice02IncTaxMin : 0}},
  9686.             \"availability\": \"{{ Product.stock_find ? \"InStock\" : \"OutOfStock\" }}\"
  9687.         }
  9688.     }
  9689.     </script>
  9690. {% endblock %}
  9691. {% block main %}
  9692.     {# option1 / option2 ラベルをカテゴリ別に決定 (sh=31, rd=43, mo=15) - block scope のため main 側でも再定義 #}
  9693.     {% set option1_label = 'オプション1' %}
  9694.     {% set option2_label = 'オプション2' %}
  9695.     {% if Product.ProductCategories is not empty %}
  9696.         {% for pcat in Product.ProductCategories %}
  9697.             {% if pcat.category_id == 31 %}{% set option1_label = 'サイズプリセット' %}{% set option2_label = '駆動方式' %}{% endif %}
  9698.             {% if pcat.category_id == 43 %}{% set option1_label = 'ランマ' %}{% set option2_label = 'タイプ' %}{% endif %}
  9699.             {% if pcat.category_id == 15 %}{% set option1_label = '棚タイプ' %}{% endif %}
  9700.             {% if pcat.category_id == 17 %}{% set option1_label = '窓タイプ' %}{% endif %}
  9701.         {% endfor %}
  9702.     {% endif %}
  9703.     <div class=\"ec-productRole\" style=\"margin-top:20px;\">
  9704.         <div class=\"ec-grid2\">
  9705.             <div class=\"ec-grid2__cell\">
  9706.                 <div class=\"ec-sliderItemRole\">
  9707. \t                {# 商品名 + ブランド名 + SNSシェア #}
  9708. \t                <div class=\"ec-productRole__title\">
  9709. \t                    <div class=\"ec-productRole__titleRow\">
  9710. \t                        <h2 class=\"ec-headingTitle\">{{ Product.name }}</h2>
  9711. \t                        <div class=\"ec-share-inline\">
  9712. \t                            <a href=\"https://twitter.com/share?url={{ app.request.uri|url_encode }}&text={{ Product.name|url_encode }}\"
  9713. \t                               class=\"share-twitter\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Xでシェア\">
  9714. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.74l7.73-8.835L1.254 2.25H8.08l4.254 5.622L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z\"/></svg>
  9715. \t                            </a>
  9716. \t                            <a href=\"https://www.instagram.com/\" class=\"share-facebook\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"Instagram\">
  9717. \t                                <svg viewBox=\"0 0 24 24\" style=\"width:15px;height:15px;fill:#fff;\"><path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z\"/></svg>
  9718. \t                            </a>
  9719. \t                            <a href=\"https://social-plugins.line.me/lineit/share?url={{ app.request.uri|url_encode }}\"
  9720. \t                               class=\"share-line\" target=\"_blank\" rel=\"noreferrer noopener\" title=\"LINEでシェア\">
  9721. \t                                <i class=\"fab fa-line\"></i>
  9722. \t                            </a>
  9723. \t                        </div>
  9724. \t                    </div>
  9725. \t                </div>
  9726.                     {% if BaseInfo.option_favorite_product %}
  9727.                      <div style=\"position:relative;top: 20px;left: 10px;z-index:100;\">
  9728. \t\t\t\t\t\t{% if is_favorite == false %}
  9729.                         <form action=\"{{ url('product_add_favorite', {id:Product.id}) }}\" method=\"post\">
  9730.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\">&#9825;</button>
  9731.                         </form>
  9732.                         {% else %}
  9733.                         <form action=\"{{ url('product_add_favorite', {id:Product.id}) }}\" method=\"post\">
  9734.                            <button type=\"submit\" id=\"favorite\" class=\"favorite\" style=\"color:red;\">&#9829;</button>
  9735.                         </form>
  9736.                         {% endif %}
  9737.                      </div>
  9738.                     {% endif %}
  9739.                     <div class=\"item_visual\">
  9740.                         {% for ProductImage in Product.ProductImage %}
  9741.                             <div class=\"slide-item\">
  9742.                                 <a class=\"js-zoom\" href=\"{{ asset(ProductImage, 'save_image') }}\" aria-label=\"{{ loop.first ? Product.name : '' }}\">
  9743.                                     <img src=\"{{ asset(ProductImage, 'save_image') }}\" alt=\"{{ loop.first ? Product.name : '' }}\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"{% if loop.index > 1 %} loading=\"lazy\"{% endif %}>
  9744.                                 </a>
  9745.                             </div>
  9746.                         {% else %}
  9747.                             <div class=\"slide-item\"><img src=\"{{ asset(''|no_image_product, 'save_image') }}\" alt=\"{{ Product.name }}\" width=\"550\" height=\"550\" style=\"max-height: 400px;\"></div>
  9748.                         {% endfor %}
  9749.                     </div>
  9750.                     <div class=\"item_nav\">
  9751.                         {% for ProductImage in Product.ProductImage %}
  9752.                             <div class=\"slideThumb\" data-index=\"{{ loop.index0 }}\"><img src=\"{{ asset(ProductImage, 'save_image') }}\" alt=\"\" width=\"80\" height=\"80\" loading=\"lazy\"></div>
  9753.                         {% endfor %}
  9754.                     </div>
  9755.                 </div>
  9756.                     {# ===== 施工エリア案内(見積シミュレーションの下)===== #}
  9757.                     <div class=\"ec-areaNotice\" style=\"margin-top:16px;margin-right:10px;\">
  9758.                         <div class=\"ec-areaNotice__inner\">
  9759.                             <div class=\"ec-areaNotice__icon\">📍</div>
  9760.                             <div class=\"ec-areaNotice__body\">
  9761.                                 <p class=\"ec-areaNotice__title\">施工対応エリアについて</p>
  9762.                                 <div class=\"ec-areaNotice__detail\">
  9763.                                     <p class=\"ec-areaNotice__text\">
  9764.                                         当店の施工サービスは、<strong>山梨県全域</strong>および<br>
  9765.                                         <strong>諏訪エリア(諏訪市・岡谷市・茅野市・諏訪郡)</strong>を対象としております。<br>
  9766.                                         上記エリア外のお客様には、商品のみのご購入が可能でございます。<br>
  9767.                                         ご不明な点がございましたら、お気軽にお問い合わせください。
  9768.                                     </p>
  9769.                                     <a class=\"ec-areaNotice__link\" href=\"{{ url('contact') }}\">エリア外のお客様・ご相談はこちら →</a>
  9770.                                 </div>
  9771.                             </div>
  9772.                         </div>
  9773.                     </div>
  9774.             </div>
  9775.             <div class=\"ec-grid2__cell2\">
  9776.                 <div class=\"ec-productRole__profile\" >
  9777.                     {# 関連カテゴリ (DIY=21 / 石材=28 / 照明=44 は非表示要件のため除外) #}
  9778.                     {% set hidden_cat_ids = [21, 28, 44] %}
  9779.                     {% if Product.ProductCategories is not empty %}
  9780.                         <div class=\"ec-productRole__category\" style=\"padding:10px 0;\">
  9781.                             {% for ProductCategory in Product.ProductCategories %}
  9782.                                 {% if ProductCategory.Category.id not in hidden_cat_ids %}
  9783.                                 <ul>
  9784.                                     <li>
  9785.                                         {% for Category in ProductCategory.Category.path %}
  9786.                                             <a href=\"{{ url('product_list') }}?category_id={{ Category.id }}\">{{ Category.name }}</a> {%- if loop.last == false %}
  9787.                                             <span>></span>{% endif -%}
  9788.                                         {% endfor %}
  9789.                                     </li>
  9790.                                 </ul>
  9791.                                 {% endif %}
  9792.                             {% endfor %}
  9793.                         </div>
  9794.                     {% endif %}
  9795.                     {# 販売価格 #}
  9796.                     <div class=\"ec-productRole__price\">
  9797. \t\t\t\t\t\t<span style=\"color:black;font-size:15px;\">工事費込み価格</span>
  9798.                         {% if Product.hasProductClass -%}
  9799.                             {% if Product.getPrice02IncTaxMin == Product.getPrice02IncTaxMax %}
  9800.                                 <div class=\"ec-price\">
  9801.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">{{ Product.getPrice02IncTaxMin|price }}</span>
  9802.                                     <span class=\"ec-price__tax\">({{ '税込'|trans }})~</span>
  9803.                                 </div>
  9804.                             {% else %}
  9805.                                 <div class=\"ec-price\">
  9806.                                     <span id=\"price02-display\" class=\"ec-price__price price02-default\">{{ Product.getPrice02IncTaxMin|price }} ~ {{ Product.getPrice02IncTaxMax|price }}</span>
  9807.                                     <span class=\"ec-price__tax\">({{ '税込'|trans }})</span>
  9808.                                 </div>
  9809.                             {% endif %}
  9810.                         {% else %}
  9811.                             <div class=\"ec-price\">
  9812.                                 <span id=\"price02-display\" class=\"ec-price__price\">{{ Product.getPrice02IncTaxMin|price }}</span>
  9813.                                     <span class=\"ec-price__tax\">({{ '税込'|trans }})~</span>
  9814.                             </div>
  9815.                         {% endif %}
  9816.                     </div>
  9817.                     {# タグ #}
  9818.                     <ul class=\"ec-productRole__tags\">
  9819.                         {% for Tag in Product.Tags %}
  9820.                             <li class=\"ec-productRole__tag tag_{{ Tag.id }}\">{{ Tag }}</li>
  9821.                         {% endfor %}
  9822.                     </ul>
  9823.                     {# 商品コード #}
  9824.                     {% if Product.code_min is not empty %}
  9825.                         <div class=\"ec-productRole__code\">
  9826.                             {{ '商品コード'|trans }}: <span class=\"product-code-default\">{{ Product.code_min }}{% if Product.code_min != Product.code_max %} ~ {{ Product.code_max }}{% endif %}</span>
  9827.                         </div>
  9828.                     {% endif %}
  9829.                     <div class=\"ec-productRole__description\">
  9830. \t\t\t\t        <div class=\"ec-rectHeading\">
  9831. \t\t\t\t            <h4>製品情報</h4>
  9832. \t\t\t\t        </div>
  9833. \t\t\t\t\t\t{{ Product.sales_infomation|raw|nl2br }}
  9834.                     </div>
  9835. \t\t\t\t\t<div class=\"card card-danger\" style=\"clear:both;margin:1px;\">
  9836. \t\t\t\t\t  <div class=\"card-header\">
  9837. \t\t\t\t\t    <h3 class=\"card-title\">見積シミュレーション</h3>
  9838. \t\t\t\t\t  </div>
  9839. \t\t\t\t\t  <div class=\"card-body p-2\">
  9840.                         {% set related_image = getProduct_field(Product.id,\"related_image\") %}
  9841.                         {# related_image は配列: [\"1段目画像あり\",\"2段目画像あり\",\"3段目画像あり\"] のうち該当するものが格納 #}
  9842.                         {% set img1 = related_image and (\"1段目画像あり\" in related_image) %}
  9843.                         {% set img2 = related_image and (\"2段目画像あり\" in related_image) %}
  9844.                         {% set img3 = related_image and (\"3段目画像あり\" in related_image) %}
  9845.                         {% set img4 = related_image and (\"4段目画像あり\" in related_image) %}
  9846. \t\t\t\t\t    {% set type1 = getProduct_field(Product.id,\"related_name1\") %}
  9847. \t\t\t\t\t\t{% set type2 = getProduct_field(Product.id,\"related_name2\") %}
  9848. \t\t\t\t\t\t{% set type3 = getProduct_field(Product.id,\"related_name3\") %}
  9849. \t\t\t\t\t\t{% set type4 = getProduct_field(Product.id,\"related_name4\") %}
  9850. \t\t\t\t\t\t{% set hasRelated = (type1 and related_product1 and related_product1|length)
  9851. \t\t\t\t\t\t                 or (type2 and related_product2 and related_product2|length)
  9852. \t\t\t\t\t\t                 or (type3 and related_product3 and related_product3|length)
  9853. \t\t\t\t\t\t                 or (type4 and related_product4 and related_product4|length) %}
  9854. \t\t\t\t\t\t{% if hasRelated %}
  9855. \t\t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のタイプを選択してください。</label></div>
  9856. \t\t\t\t\t\t{% endif %}
  9857. \t\t\t\t\t\t{# ===== 1段目 ===== #}
  9858. \t\t\t\t\t\t{% if type1 and related_product1 and related_product1|length %}
  9859. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  9860. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type1 }}{% if img1 and base_select1 %}: <span>{{ base_select1 }}</span>{% endif %}</div>
  9861. \t\t\t\t\t\t  {% if img1 %}
  9862. \t\t\t\t\t\t    {# --- 画像付きカード --- #}
  9863. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  9864. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product1 %}
  9865. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select1 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9866. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  9867. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  9868. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  9869. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  9870. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  9871. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  9872. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  9873. \t\t\t\t\t\t        </a>
  9874. \t\t\t\t\t\t      {% endfor %}
  9875. \t\t\t\t\t\t    </div>
  9876. \t\t\t\t\t\t  {% else %}
  9877. \t\t\t\t\t\t    {# --- ボタン式ラジオ --- #}
  9878. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  9879. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product1 %}
  9880. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select1 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9881. \t\t\t\t\t\t          {{ rp_name }}
  9882. \t\t\t\t\t\t        </a>
  9883. \t\t\t\t\t\t      {% endfor %}
  9884. \t\t\t\t\t\t    </div>
  9885. \t\t\t\t\t\t  {% endif %}
  9886. \t\t\t\t\t\t</div>
  9887. \t\t\t\t\t\t{% endif %}
  9888. \t\t\t\t\t\t{# ===== 2段目 ===== #}
  9889. \t\t\t\t\t\t{% if type2 and related_product2 and related_product2|length %}
  9890. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  9891. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type2 }}{% if img2 and base_select2 %}: <span>{{ base_select2 }}</span>{% endif %}</div>
  9892. \t\t\t\t\t\t  {% if img2 %}
  9893. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  9894. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product2 %}
  9895. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select2 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9896. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  9897. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  9898. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  9899. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  9900. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  9901. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  9902. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  9903. \t\t\t\t\t\t        </a>
  9904. \t\t\t\t\t\t      {% endfor %}
  9905. \t\t\t\t\t\t    </div>
  9906. \t\t\t\t\t\t  {% else %}
  9907. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  9908. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product2 %}
  9909. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select2 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9910. \t\t\t\t\t\t          {{ rp_name }}
  9911. \t\t\t\t\t\t        </a>
  9912. \t\t\t\t\t\t      {% endfor %}
  9913. \t\t\t\t\t\t    </div>
  9914. \t\t\t\t\t\t  {% endif %}
  9915. \t\t\t\t\t\t</div>
  9916. \t\t\t\t\t\t{% endif %}
  9917. \t\t\t\t\t\t{# ===== 3段目 ===== #}
  9918. \t\t\t\t\t\t{% if type3 and related_product3 and related_product3|length %}
  9919. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  9920. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type3 }}{% if img3 and base_select3 %}: <span>{{ base_select3 }}</span>{% endif %}</div>
  9921. \t\t\t\t\t\t  {% if img3 %}
  9922. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  9923. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product3 %}
  9924. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select3 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9925. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  9926. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  9927. \t\t\t\t\t\t               alt=\"{{ rp_name }}\"
  9928. \t\t\t\t\t\t               width=\"120\" height=\"120\" loading=\"lazy\"
  9929. \t\t\t\t\t\t               onerror=\"this.style.display='none';this.nextElementSibling.style.display='flex';\">
  9930. \t\t\t\t\t\t          <div class=\"rp-card__placeholder\" style=\"display:none;\">📦</div>
  9931. \t\t\t\t\t\t          <span class=\"rp-card__name\">{{ rp_name }}</span>
  9932. \t\t\t\t\t\t        </a>
  9933. \t\t\t\t\t\t      {% endfor %}
  9934. \t\t\t\t\t\t    </div>
  9935. \t\t\t\t\t\t  {% else %}
  9936. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  9937. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product3 %}
  9938. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select3 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9939. \t\t\t\t\t\t          {{ rp_name }}
  9940. \t\t\t\t\t\t        </a>
  9941. \t\t\t\t\t\t      {% endfor %}
  9942. \t\t\t\t\t\t    </div>
  9943. \t\t\t\t\t\t  {% endif %}
  9944. \t\t\t\t\t\t</div>
  9945. \t\t\t\t\t\t{% endif %}
  9946. \t\t\t\t\t\t{# ===== 4段目 ===== #}
  9947. \t\t\t\t\t\t{% if type4 and related_product4 and related_product4|length %}
  9948. \t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  9949. \t\t\t\t\t\t  <div class=\"rp-section-label\">{{ type4 }}{% if img4 and base_select4 %}: <span>{{ base_select4 }}</span>{% endif %}</div>
  9950. \t\t\t\t\t\t  {% if img4 %}
  9951. \t\t\t\t\t\t    {# --- 画像付きカード --- #}
  9952. \t\t\t\t\t\t    <div class=\"rp-card-group\">
  9953. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product4 %}
  9954. \t\t\t\t\t\t        <a class=\"rp-card{% if base_select4 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9955. \t\t\t\t\t\t          <img class=\"rp-card__image\"
  9956. \t\t\t\t\t\t               src=\"{{ (related_image_obj[rp_id] is defined and related_image_obj[rp_id]) ? asset(related_image_obj[rp_id], 'save_image') : asset(''|no_image_product, 'save_image') }}\"
  9957. \t\t\t\t\t\t               alt=\"{{ rp_name }}\" width=\"120\" height=\"120\" loading=\"lazy\">
  9958. \t\t\t\t\t\t          <span class=\"rp-card__label\">{{ rp_name }}</span>
  9959. \t\t\t\t\t\t        </a>
  9960. \t\t\t\t\t\t      {% endfor %}
  9961. \t\t\t\t\t\t    </div>
  9962. \t\t\t\t\t\t  {% else %}
  9963. \t\t\t\t\t\t    {# --- ボタン式ラジオ --- #}
  9964. \t\t\t\t\t\t    <div class=\"rp-btn-group\">
  9965. \t\t\t\t\t\t      {% for rp_id, rp_name in related_product4 %}
  9966. \t\t\t\t\t\t        <a class=\"rp-btn{% if base_select4 == rp_name %} is-selected{% endif %}\" href=\"/products/detail/{{ rp_id }}\">
  9967. \t\t\t\t\t\t          {{ rp_name }}
  9968. \t\t\t\t\t\t        </a>
  9969. \t\t\t\t\t\t      {% endfor %}
  9970. \t\t\t\t\t\t    </div>
  9971. \t\t\t\t\t\t  {% endif %}
  9972. \t\t\t\t\t\t</div>
  9973. \t\t\t\t\t\t{% endif %}
  9974. \t\t\t\t\t    {# ガレージ等で全オプション空のときに見出しのみ表示される事象を回避.
  9975. \t\t\t\t\t       色 / 寸法 / 素材 / option1/2 / op_data いずれかに「描画される」要素がある場合のみ
  9976. \t\t\t\t\t       「この商品のオプションを選択してください。」見出しを表示する.
  9977. \t\t\t\t\t       op_data は cg=9 で「残土」 / gs=27 で「撤去」「残土」を後段ループで
  9978. \t\t\t\t\t       hide するため、単純な op|length > 0 では「見出しだけ残る」事象が
  9979. \t\t\t\t\t       wh / cg の一部商品で発生していた. 描画される entry を事前カウントする. #}
  9980. \t\t\t\t\t    {% set is_gs_h = false %}
  9981. \t\t\t\t\t    {% set is_cg_h = false %}
  9982. \t\t\t\t\t    {% if Product.ProductCategories is not empty %}
  9983. \t\t\t\t\t        {% for pc_h in Product.ProductCategories %}
  9984. \t\t\t\t\t            {% if pc_h.category_id == 27 %}{% set is_gs_h = true %}{% endif %}
  9985. \t\t\t\t\t            {% if pc_h.category_id == 9  %}{% set is_cg_h = true %}{% endif %}
  9986. \t\t\t\t\t        {% endfor %}
  9987. \t\t\t\t\t    {% endif %}
  9988. \t\t\t\t\t    {% set visible_op_count = 0 %}
  9989. \t\t\t\t\t    {% if op and op|length %}
  9990. \t\t\t\t\t        {% for opi in op %}
  9991. \t\t\t\t\t            {% if opi['name'] %}
  9992. \t\t\t\t\t                {% set _hide_h = false %}
  9993. \t\t\t\t\t                {% if is_gs_h and (opi['name'] matches '/撤去/' or opi['name'] matches '/残土/') %}{% set _hide_h = true %}{% endif %}
  9994. \t\t\t\t\t                {% if is_cg_h and opi['name'] matches '/残土/' %}{% set _hide_h = true %}{% endif %}
  9995. \t\t\t\t\t                {% if not _hide_h %}{% set visible_op_count = visible_op_count + 1 %}{% endif %}
  9996. \t\t\t\t\t            {% endif %}
  9997. \t\t\t\t\t        {% endfor %}
  9998. \t\t\t\t\t    {% endif %}
  9999. \t\t\t\t\t    {% set has_any_option =
  10000. \t\t\t\t\t        (color and color|length and ProductClass.SaleType.id != 3)
  10001. \t\t\t\t\t        or (p_w and p_w|length and p_w|join != \"\")
  10002. \t\t\t\t\t        or (p_d and p_d|length and p_d|join != \"\")
  10003. \t\t\t\t\t        or (p_h and p_h|length and p_h|join != \"\")
  10004. \t\t\t\t\t        or (p_m and p_m|length and p_m|join != \"\")
  10005. \t\t\t\t\t        or (p_option1 and p_option1|length and p_option1|join != \"\")
  10006. \t\t\t\t\t        or (p_option2 and p_option2|length and p_option2|join != \"\")
  10007. \t\t\t\t\t        or ProductClass.SaleType.id in [2, 5, 6, 7, 9]
  10008. \t\t\t\t\t    %}
  10009. \t\t\t\t\t    {% if has_any_option %}
  10010. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">この商品のオプションを選択してください。</label></div>
  10011. \t\t\t\t\t    {% endif %}
  10012.                         {# sale_type=2 (補助金窓) はタイプごとに個別カラー選択するため共通カラーは非表示 #}
  10013.                         {% if color and color|length and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 2 %}
  10014.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10015.                           <div class=\"rp-section-label\">カラー{% if mitsumori_json and mitsumori_json.pc %}: <span>{{ mitsumori_json.pc }}</span>{% endif %}</div>
  10016.                           <div class=\"opt-btn-group\">
  10017.                             {% set idx = 0 %}
  10018.                             {% for cc in color %}{% if cc and cc['name'] %}{% set idx = idx + 1 %}
  10019.                               {% set has_img = cc['img'] is defined and cc['img'] is not empty %}
  10020.                               <label class=\"opt-btn{% if has_img %} opt-btn--with-image{% endif %}{% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %} is-selected{% endif %}\"
  10021.                                      onclick=\"mitsumori_simulation_val('pc', '{{ cc['name']|e('js') }}');\">
  10022.                                 <input type=\"radio\" name=\"color\" id=\"cc_{{ idx }}\" value=\"{{ cc['name'] }}\"
  10023.                                        {% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %}checked{% endif %}>
  10024.                                 {% if has_img %}
  10025.                                   <img src=\"{{ cc['img'] }}\" alt=\"{{ cc['name'] }}\" class=\"opt-btn__img\"
  10026.                                        onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  10027.                                   <span class=\"opt-btn__name\">{{ cc['name'] }}</span>
  10028.                                 {% else %}
  10029.                                   {{ cc['name'] }}
  10030.                                 {% endif %}
  10031.                               </label>
  10032.                             {% endif %}{% endfor %}
  10033.                           </div>
  10034.                         </div>
  10035.                         {% endif %}
  10036.                         {# sale_type=2 (補助金窓) はタイプごとに個別幅選択するため共通幅は非表示.
  10037.                            tf (人工芝, sale_type=6) は専用の「芝の幅」+「施工サイズ」UI を下部に持つため、
  10038.                            汎用の 幅/奥行/高さ は描画しない (両方出すと name=\"pw\"/\"ph\" が重複し、
  10039.                            片方を選ぶともう片方の選択が外れる顧客指摘あり). #}
  10040.                         {% if p_w and p_w|length and p_w|join != \"\" and ProductClass.SaleType.id not in [2, 3, 6] %}
  10041.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10042.                           <div class=\"rp-section-label\">幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  10043.                           <div class=\"opt-btn-group\">
  10044.                             {% set idx = 0 %}
  10045.                             {% for pw in p_w %}{% if pw %}{% set idx = idx + 1 %}
  10046.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw) or p_w|length == 1 %} is-selected{% endif %}\"
  10047.                                      onclick=\"mitsumori_simulation_val('pw', '{{ pw|e('js') }}');\">
  10048.                                 <input type=\"radio\" name=\"pw\" id=\"pw_{{ idx }}\" value=\"{{ pw }}\"
  10049.                                        {% if (mitsumori_json and mitsumori_json.pw == pw) or p_w|length == 1 %}checked{% endif %}>
  10050.                                 {{ pw }}
  10051.                               </label>
  10052.                             {% endif %}{% endfor %}
  10053.                           </div>
  10054.                         </div>
  10055.                         {% endif %}
  10056.                         {% if p_d and p_d|length and p_d|join != \"\" and ProductClass.SaleType.id not in [3, 6] %}
  10057.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10058.                           <div class=\"rp-section-label\">奥行き{% if mitsumori_json and mitsumori_json.pd %}: <span>{{ mitsumori_json.pd }}</span>{% endif %}</div>
  10059.                           <div class=\"opt-btn-group\">
  10060.                             {% set idx = 0 %}
  10061.                             {% for pd in p_d %}{% if pd %}{% set idx = idx + 1 %}
  10062.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pd == pd) or p_d|length == 1 %} is-selected{% endif %}\"
  10063.                                      onclick=\"mitsumori_simulation_val('pd', '{{ pd|e('js') }}');\">
  10064.                                 <input type=\"radio\" name=\"pd\" id=\"pd_{{ idx }}\" value=\"{{ pd }}\"
  10065.                                        {% if (mitsumori_json and mitsumori_json.pd == pd) or p_d|length == 1 %}checked{% endif %}>
  10066.                                 {{ pd }}
  10067.                               </label>
  10068.                             {% endif %}{% endfor %}
  10069.                           </div>
  10070.                         </div>
  10071.                         {% endif %}
  10072.                         {# sale_type=2 (補助金窓) はタイプごとに個別高さ選択するため共通高さは非表示.
  10073.                            sale_type=6 (人工芝) は専用 UI なので汎用高さは描画しない. #}
  10074.                         {% if p_h and p_h|length and p_h|join != \"\" and ProductClass.SaleType.id not in [2, 3, 6] %}
  10075.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10076.                           <div class=\"rp-section-label\">高さ{% if mitsumori_json and mitsumori_json.ph %}: <span>{{ mitsumori_json.ph }}</span>{% endif %}</div>
  10077.                           <div class=\"opt-btn-group\">
  10078.                             {% set idx = 0 %}
  10079.                             {% for ph in p_h %}{% if ph %}{% set idx = idx + 1 %}
  10080.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.ph == ph) or p_h|length == 1 %} is-selected{% endif %}\"
  10081.                                      onclick=\"mitsumori_simulation_val('ph', '{{ ph|e('js') }}');\">
  10082.                                 <input type=\"radio\" name=\"ph\" id=\"ph_{{ idx }}\" value=\"{{ ph }}\"
  10083.                                        {% if (mitsumori_json and mitsumori_json.ph == ph) or p_h|length == 1 %}checked{% endif %}>
  10084.                                 {{ ph }}
  10085.                               </label>
  10086.                             {% endif %}{% endfor %}
  10087.                           </div>
  10088.                         </div>
  10089.                         {% endif %}
  10090.                         {# sale_type=2 (補助金窓) はタイプごとに個別ガラス選択するため共通素材は非表示 #}
  10091.                         {% if p_m and p_m|length and p_m|join != \"\" and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 2 %}
  10092.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10093.                           <div class=\"rp-section-label\">素材{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  10094.                           <div class=\"opt-btn-group\">
  10095.                             {% set idx = 0 %}
  10096.                             {% for pm in p_m %}{% if pm %}{% set idx = idx + 1 %}
  10097.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm) or p_m|length == 1 %} is-selected{% endif %}\"
  10098.                                      onclick=\"mitsumori_simulation_val('pm', '{{ pm|e('js') }}');\">
  10099.                                 <input type=\"radio\" name=\"pm\" id=\"pm_{{ idx }}\" value=\"{{ pm }}\"
  10100.                                        {% if (mitsumori_json and mitsumori_json.pm == pm) or p_m|length == 1 %}checked{% endif %}>
  10101.                                 {{ pm }}
  10102.                               </label>
  10103.                             {% endif %}{% endfor %}
  10104.                           </div>
  10105.                         </div>
  10106.                         {% endif %}
  10107.                         {# option1 (sale_type 2 は専用 UI が下にあるため除外 / sale_type 3 は下部ブロックで描画 /
  10108.                            sale_type 4 = fe・ts は option1 が ct_unit_price (枚数増分の工事費単価) で
  10109.                            ユーザー選択肢ではなく計算用の内部値のため radio として表示しない. 値は
  10110.                            上の auto-init (p_option1|length == 1) で JS の option1 変数に埋め込み済み) #}
  10111.                         {% if p_option1 and p_option1|length and p_option1|join != \"\" and ProductClass.SaleType.id != 2 and ProductClass.SaleType.id != 3 and ProductClass.SaleType.id != 4 %}
  10112.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10113.                           <div class=\"rp-section-label\">{{ option1_label }}{% if mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 %}: <span>{{ mitsumori_json.option1 }}</span>{% endif %}</div>
  10114.                           <div class=\"opt-btn-group\">
  10115.                             {% set idx = 0 %}
  10116.                             {% for opt1 in p_option1 %}{% if opt1 %}{% set idx = idx + 1 %}
  10117.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1) or p_option1|length == 1 %} is-selected{% endif %}\"
  10118.                                      onclick=\"mitsumori_simulation_val('option1', '{{ opt1|e('js') }}');\">
  10119.                                 <input type=\"radio\" name=\"option1\" id=\"option1_{{ idx }}\" value=\"{{ opt1 }}\"
  10120.                                        {% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1) or p_option1|length == 1 %}checked{% endif %}>
  10121.                                 {{ opt1 }}
  10122.                               </label>
  10123.                             {% endif %}{% endfor %}
  10124.                           </div>
  10125.                         </div>
  10126.                         {% endif %}
  10127.                         {# option2 #}
  10128.                         {% if p_option2 and p_option2|length and p_option2|join != \"\" and ProductClass.SaleType.id != 2 and ProductClass.SaleType.id != 3 %}
  10129.                         <div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10130.                           <div class=\"rp-section-label\">{{ option2_label }}{% if mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 %}: <span>{{ mitsumori_json.option2 }}</span>{% endif %}</div>
  10131.                           <div class=\"opt-btn-group\">
  10132.                             {% set idx = 0 %}
  10133.                             {% for opt2 in p_option2 %}{% if opt2 %}{% set idx = idx + 1 %}
  10134.                               <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 == opt2) or p_option2|length == 1 %} is-selected{% endif %}\"
  10135.                                      onclick=\"mitsumori_simulation_val('option2', '{{ opt2|e('js') }}');\">
  10136.                                 <input type=\"radio\" name=\"option2\" id=\"option2_{{ idx }}\" value=\"{{ opt2 }}\"
  10137.                                        {% if (mitsumori_json and mitsumori_json.option2 is defined and mitsumori_json.option2 == opt2) or p_option2|length == 1 %}checked{% endif %}>
  10138.                                 {{ opt2 }}
  10139.                               </label>
  10140.                             {% endif %}{% endfor %}
  10141.                           </div>
  10142.                         </div>
  10143.                         {% endif %}
  10144. \t\t\t\t\t\t<!-- 1: 施工見積(通常) → 幅/奥行/高さ/素材/カラーは上部の共通ブロックで表示済み -->
  10145. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 1 %}
  10146. \t\t\t\t\t\t{% endif %}
  10147. \t\t\t\t\t\t<!-- 2: 施工見積(補助金・窓) 複数タイプ追加対応 (2026-05) -->
  10148. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 2 %}
  10149. \t\t\t\t\t\t\t{# 2026-05 改修: ex-shop プラメイク方式に倣い、1 商品で
  10150. \t\t\t\t\t\t\t   複数の「窓タイプ」(subtype × 幅 × 高さ × ガラス × カラー × セット数)
  10151. \t\t\t\t\t\t\t   を追加できる UI に変更. 各タイプは内訳 JSON として 1 明細にまとめる. #}
  10152. \t\t\t\t\t\t\t{# ec-productRole__profile は標準テンプレで height:600px / overflow:auto
  10153. \t\t\t\t\t\t\t   が当たっており、複数タイプ追加カードが内部スクロールに押し込まれて
  10154. \t\t\t\t\t\t\t   見えない. sale_type=2 のときだけ縦方向に伸ばす. #}
  10155. \t\t\t\t\t\t\t<style>
  10156. \t\t\t\t\t\t\t\t.ec-productRole__profile {
  10157. \t\t\t\t\t\t\t\t\toverflow: visible !important;
  10158. \t\t\t\t\t\t\t\t\tmax-height: none !important;
  10159. \t\t\t\t\t\t\t\t\theight: auto !important;
  10160. \t\t\t\t\t\t\t\t}
  10161. \t\t\t\t\t\t\t</style>
  10162. \t\t\t\t\t\t\t{# 住宅区分 UI: 補助金単価が戸建 / 集合住宅で異なるためお客様に申告いただく. #}
  10163. \t\t\t\t\t\t\t{% set housing_default = getProduct_field(Product.id, '住宅区分')|default('戸建') %}
  10164. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  10165. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  10166. \t\t\t\t\t\t\t    <strong>お住まいの種別を選択</strong>
  10167. \t\t\t\t\t\t\t    <small class=\"ms-2 text-muted\">補助金単価が変わります</small>
  10168. \t\t\t\t\t\t\t  </div>
  10169. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  10170. \t\t\t\t\t\t\t    <div class=\"opt-btn-group\" id=\"window-housing-type-group\">
  10171. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  10172. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"戸建\"
  10173. \t\t\t\t\t\t\t               {% if housing_default != '集合住宅' %}checked{% endif %}>
  10174. \t\t\t\t\t\t\t        戸建住宅<small class=\"d-block text-muted\">(延床240㎡以下の非住宅含む)</small>
  10175. \t\t\t\t\t\t\t      </label>
  10176. \t\t\t\t\t\t\t      <label class=\"opt-btn\">
  10177. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"window_housing_type\" value=\"集合住宅\"
  10178. \t\t\t\t\t\t\t               {% if housing_default == '集合住宅' %}checked{% endif %}>
  10179. \t\t\t\t\t\t\t        集合住宅<small class=\"d-block text-muted\">(低層・中高層/240㎡超の非住宅)</small>
  10180. \t\t\t\t\t\t\t      </label>
  10181. \t\t\t\t\t\t\t    </div>
  10182. \t\t\t\t\t\t\t  </div>
  10183. \t\t\t\t\t\t\t</div>
  10184. \t\t\t\t\t\t\t<div class=\"card mt-3 mb-3\">
  10185. \t\t\t\t\t\t\t  <div class=\"card-header\" style=\"background:#fff3cd;color:#333;\">
  10186. \t\t\t\t\t\t\t    <strong>窓タイプを選択(複数追加可・最大 20)</strong>
  10187. \t\t\t\t\t\t\t  </div>
  10188. \t\t\t\t\t\t\t  <div class=\"card-body p-2\">
  10189. \t\t\t\t\t\t\t    <div id=\"window-types-container\"><!-- 動的に窓タイプブロックが追加される --></div>
  10190. \t\t\t\t\t\t\t    <div class=\"text-center mt-2\">
  10191. \t\t\t\t\t\t\t      <button type=\"button\" id=\"btn-add-window-type\" class=\"btn btn-outline-primary btn-sm\" onclick=\"addWindowType();\">+ 窓タイプを追加</button>
  10192. \t\t\t\t\t\t\t      <div class=\"small text-muted mt-1\">最大 20 タイプまで追加できます</div>
  10193. \t\t\t\t\t\t\t    </div>
  10194. \t\t\t\t\t\t\t  </div>
  10195. \t\t\t\t\t\t\t</div>
  10196. \t\t\t\t\t\t\t{# 窓タイプブロックのテンプレート. __IDX__ を JS で連番に置換して clone する. #}
  10197. \t\t\t\t\t\t\t<template id=\"window-type-template\">
  10198. \t\t\t\t\t\t\t  <div class=\"window-type-block\" data-type-idx=\"__IDX__\" style=\"border:1px solid #ddd;border-radius:6px;padding:10px;margin-bottom:10px;background:#fafafa;\">
  10199. \t\t\t\t\t\t\t    <div class=\"d-flex justify-content-between align-items-center mb-2\">
  10200. \t\t\t\t\t\t\t      <strong>窓タイプ <span class=\"wt-num\">__IDX__</span></strong>
  10201. \t\t\t\t\t\t\t      <button type=\"button\" class=\"btn btn-sm btn-outline-danger btn-remove-window-type\" onclick=\"removeWindowType(this);\">× 削除</button>
  10202. \t\t\t\t\t\t\t    </div>
  10203. \t\t\t\t\t\t\t    {# 窓タイプ (subtype) #}
  10204. \t\t\t\t\t\t\t    {% if p_option1 and p_option1|length and p_option1|join != \"\" %}
  10205. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10206. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓タイプ</div>
  10207. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  10208. \t\t\t\t\t\t\t        {% for v in p_option1 %}{% if v %}
  10209. \t\t\t\t\t\t\t          <label class=\"opt-btn\">
  10210. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_subtype___IDX__\" value=\"{{ v }}\" data-axis=\"subtype\" onchange=\"onWindowTypeAxisChange(this);\">
  10211. \t\t\t\t\t\t\t            {{ v }}
  10212. \t\t\t\t\t\t\t          </label>
  10213. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  10214. \t\t\t\t\t\t\t      </div>
  10215. \t\t\t\t\t\t\t    </div>
  10216. \t\t\t\t\t\t\t    {% endif %}
  10217. \t\t\t\t\t\t\t    {# 幅 (mm 直接入力) #}
  10218. \t\t\t\t\t\t\t    {% if p_w and p_w|length and p_w|join != \"\" %}
  10219. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10220. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">幅</div>
  10221. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  10222. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_pw___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  10223. \t\t\t\t\t\t\t               placeholder=\"例 1750\" data-axis=\"pw\" data-unit=\"mm\"
  10224. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  10225. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  10226. \t\t\t\t\t\t\t      </div>
  10227. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応幅: 〜{{ (p_w|last)|default('') }}({{ p_w|length }} 段階の価格帯から自動選択)</small>
  10228. \t\t\t\t\t\t\t    </div>
  10229. \t\t\t\t\t\t\t    {% endif %}
  10230. \t\t\t\t\t\t\t    {# 高さ (mm 直接入力) #}
  10231. \t\t\t\t\t\t\t    {% if p_h and p_h|length and p_h|join != \"\" %}
  10232. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10233. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">高さ</div>
  10234. \t\t\t\t\t\t\t      <div class=\"input-group\" style=\"max-width:240px;\">
  10235. \t\t\t\t\t\t\t        <input type=\"number\" name=\"wt_ph___IDX__\" class=\"form-control\" min=\"100\" step=\"10\"
  10236. \t\t\t\t\t\t\t               placeholder=\"例 1200\" data-axis=\"ph\" data-unit=\"mm\"
  10237. \t\t\t\t\t\t\t               oninput=\"onWindowTypeAxisChange(this);\">
  10238. \t\t\t\t\t\t\t        <span class=\"input-group-text\">mm</span>
  10239. \t\t\t\t\t\t\t      </div>
  10240. \t\t\t\t\t\t\t      <small class=\"text-muted\">商品の対応高さ: 〜{{ (p_h|last)|default('') }}({{ p_h|length }} 段階の価格帯から自動選択)</small>
  10241. \t\t\t\t\t\t\t    </div>
  10242. \t\t\t\t\t\t\t    {% endif %}
  10243. \t\t\t\t\t\t\t    {# ガラスタイプ #}
  10244. \t\t\t\t\t\t\t    {% if p_m and p_m|length and p_m|join != \"\" %}
  10245. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10246. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">ガラスタイプ</div>
  10247. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  10248. \t\t\t\t\t\t\t        {% for v in p_m %}{% if v %}
  10249. \t\t\t\t\t\t\t          <label class=\"opt-btn\">
  10250. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pm___IDX__\" value=\"{{ v }}\" data-axis=\"pm\" onchange=\"onWindowTypeAxisChange(this);\">
  10251. \t\t\t\t\t\t\t            {{ v }}
  10252. \t\t\t\t\t\t\t          </label>
  10253. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  10254. \t\t\t\t\t\t\t      </div>
  10255. \t\t\t\t\t\t\t      <small class=\"text-muted\">「<span style=\"color:#2e7d32;font-weight:bold;\">補助金対象</span>」が付いたガラスは、先進的窓リノベ補助金の対象です。</small>
  10256. \t\t\t\t\t\t\t    </div>
  10257. \t\t\t\t\t\t\t    {% endif %}
  10258. \t\t\t\t\t\t\t    {# 窓枠カラー #}
  10259. \t\t\t\t\t\t\t    {% if color and color|length %}
  10260. \t\t\t\t\t\t\t    <div class=\"form-group mt-2 pb-2\" style=\"border-bottom:1px dashed rgba(0,0,0,.1)\">
  10261. \t\t\t\t\t\t\t      <div class=\"rp-section-label\">窓枠カラー</div>
  10262. \t\t\t\t\t\t\t      <div class=\"opt-btn-group\">
  10263. \t\t\t\t\t\t\t        {% for cc in color %}{% if cc and cc['name'] %}
  10264. \t\t\t\t\t\t\t          {% set has_img = cc['img'] is defined and cc['img'] is not empty %}
  10265. \t\t\t\t\t\t\t          <label class=\"opt-btn{% if has_img %} opt-btn--with-image{% endif %}\">
  10266. \t\t\t\t\t\t\t            <input type=\"radio\" name=\"wt_pc___IDX__\" value=\"{{ cc['name'] }}\" data-axis=\"pc\" onchange=\"onWindowTypeAxisChange(this);\">
  10267. \t\t\t\t\t\t\t            {% if has_img %}
  10268. \t\t\t\t\t\t\t              <img src=\"{{ cc['img'] }}\" alt=\"{{ cc['name'] }}\" class=\"opt-btn__img\"
  10269. \t\t\t\t\t\t\t                   onerror=\"this.parentNode.classList.remove('opt-btn--with-image'); this.remove();\">
  10270. \t\t\t\t\t\t\t              <span class=\"opt-btn__name\">{{ cc['name'] }}</span>
  10271. \t\t\t\t\t\t\t            {% else %}
  10272. \t\t\t\t\t\t\t              {{ cc['name'] }}
  10273. \t\t\t\t\t\t\t            {% endif %}
  10274. \t\t\t\t\t\t\t          </label>
  10275. \t\t\t\t\t\t\t        {% endif %}{% endfor %}
  10276. \t\t\t\t\t\t\t      </div>
  10277. \t\t\t\t\t\t\t    </div>
  10278. \t\t\t\t\t\t\t    {% endif %}
  10279. \t\t\t\t\t\t\t    {# セット数 + タイプごとの補助金額表示 (補助金は task 2 で実計算) #}
  10280. \t\t\t\t\t\t\t    <div class=\"form-group row mt-2 align-items-center\">
  10281. \t\t\t\t\t\t\t      <label class=\"col-4 col-form-label\">セット数</label>
  10282. \t\t\t\t\t\t\t      <div class=\"col-4\">
  10283. \t\t\t\t\t\t\t        <div class=\"input-group\">
  10284. \t\t\t\t\t\t\t          <input type=\"number\" name=\"wt_setqty___IDX__\" class=\"form-control wt-input-setqty\" value=\"1\" min=\"1\" max=\"99\" data-axis=\"setqty\" onchange=\"onWindowTypeAxisChange(this);\">
  10285. \t\t\t\t\t\t\t          <span class=\"input-group-text\">セット</span>
  10286. \t\t\t\t\t\t\t        </div>
  10287. \t\t\t\t\t\t\t      </div>
  10288. \t\t\t\t\t\t\t      <div class=\"col-4 text-end\">
  10289. \t\t\t\t\t\t\t        <small class=\"text-muted\">補助金額<br><span class=\"wt-subsidy-amount\">―</span> 円</small>
  10290. \t\t\t\t\t\t\t      </div>
  10291. \t\t\t\t\t\t\t    </div>
  10292. \t\t\t\t\t\t\t  </div>
  10293. \t\t\t\t\t\t\t</template>
  10294. \t\t\t\t\t\t\t{# 複数タイプ管理 JS. addWindowType / removeWindowType / 再番号付け. #}
  10295. \t\t\t\t\t\t\t<script>
  10296. \t\t\t\t\t\t\t(function() {
  10297. \t\t\t\t\t\t\t\tvar MAX_WINDOW_TYPES = 20;
  10298. \t\t\t\t\t\t\t\tfunction addWindowType() {
  10299. \t\t\t\t\t\t\t\t\tvar container = document.getElementById('window-types-container');
  10300. \t\t\t\t\t\t\t\t\tif (!container) return;
  10301. \t\t\t\t\t\t\t\t\tvar existing = container.querySelectorAll('.window-type-block');
  10302. \t\t\t\t\t\t\t\t\tif (existing.length >= MAX_WINDOW_TYPES) return;
  10303. \t\t\t\t\t\t\t\t\tvar newIdx = existing.length + 1;
  10304. \t\t\t\t\t\t\t\t\tvar tpl = document.getElementById('window-type-template');
  10305. \t\t\t\t\t\t\t\t\tif (!tpl) return;
  10306. \t\t\t\t\t\t\t\t\t// <template> の innerHTML を取り出して __IDX__ を新規連番に置換し、要素化して append.
  10307. \t\t\t\t\t\t\t\t\tvar html = tpl.innerHTML.replace(/__IDX__/g, String(newIdx));
  10308. \t\t\t\t\t\t\t\t\tvar wrapper = document.createElement('div');
  10309. \t\t\t\t\t\t\t\t\twrapper.innerHTML = html.trim();
  10310. \t\t\t\t\t\t\t\t\tvar block = wrapper.firstChild;
  10311. \t\t\t\t\t\t\t\t\tcontainer.appendChild(block);
  10312. \t\t\t\t\t\t\t\t\tdecorateSubsidyGlass(block);
  10313. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  10314. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10315. \t\t\t\t\t\t\t\t}
  10316. \t\t\t\t\t\t\t\t// 補助金対象ガラスの選択肢に「補助金対象」バッジ + 緑枠を付与する.
  10317. \t\t\t\t\t\t\t\t// 判定は calc script 側の window.glassYieldsSubsidy に委譲 (ロジック二重化を避ける)。
  10318. \t\t\t\t\t\t\t\tfunction decorateSubsidyGlass(block) {
  10319. \t\t\t\t\t\t\t\t\tif (!block || typeof window.glassYieldsSubsidy !== 'function') return;
  10320. \t\t\t\t\t\t\t\t\tvar radios = block.querySelectorAll('input[data-axis=\"pm\"]');
  10321. \t\t\t\t\t\t\t\t\tradios.forEach(function(inp) {
  10322. \t\t\t\t\t\t\t\t\t\tvar label = inp.closest('.opt-btn');
  10323. \t\t\t\t\t\t\t\t\t\tif (!label || label.querySelector('.opt-btn__subsidy-badge')) return;
  10324. \t\t\t\t\t\t\t\t\t\tif (window.glassYieldsSubsidy(inp.value)) {
  10325. \t\t\t\t\t\t\t\t\t\t\tlabel.classList.add('opt-btn--subsidy');
  10326. \t\t\t\t\t\t\t\t\t\t\tvar badge = document.createElement('span');
  10327. \t\t\t\t\t\t\t\t\t\t\tbadge.className = 'opt-btn__subsidy-badge';
  10328. \t\t\t\t\t\t\t\t\t\t\tbadge.textContent = '補助金対象';
  10329. \t\t\t\t\t\t\t\t\t\t\tlabel.appendChild(badge);
  10330. \t\t\t\t\t\t\t\t\t\t}
  10331. \t\t\t\t\t\t\t\t\t});
  10332. \t\t\t\t\t\t\t\t}
  10333. \t\t\t\t\t\t\t\tfunction removeWindowType(btn) {
  10334. \t\t\t\t\t\t\t\t\tvar block = btn.closest('.window-type-block');
  10335. \t\t\t\t\t\t\t\t\tif (!block) return;
  10336. \t\t\t\t\t\t\t\t\tblock.remove();
  10337. \t\t\t\t\t\t\t\t\treindexBlocks();
  10338. \t\t\t\t\t\t\t\t\tupdateRemoveButtonVisibility();
  10339. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10340. \t\t\t\t\t\t\t\t}
  10341. \t\t\t\t\t\t\t\tfunction updateRemoveButtonVisibility() {
  10342. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  10343. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b) {
  10344. \t\t\t\t\t\t\t\t\t\tvar btn = b.querySelector('.btn-remove-window-type');
  10345. \t\t\t\t\t\t\t\t\t\tif (btn) btn.style.display = blocks.length > 1 ? '' : 'none';
  10346. \t\t\t\t\t\t\t\t\t});
  10347. \t\t\t\t\t\t\t\t}
  10348. \t\t\t\t\t\t\t\tfunction reindexBlocks() {
  10349. \t\t\t\t\t\t\t\t\t// ブロック削除後に 1 から振り直し. input[name] の末尾 _N も書き換える.
  10350. \t\t\t\t\t\t\t\t\tvar blocks = document.querySelectorAll('#window-types-container .window-type-block');
  10351. \t\t\t\t\t\t\t\t\tblocks.forEach(function(b, i) {
  10352. \t\t\t\t\t\t\t\t\t\tvar n = i + 1;
  10353. \t\t\t\t\t\t\t\t\t\tb.setAttribute('data-type-idx', String(n));
  10354. \t\t\t\t\t\t\t\t\t\tvar numSpan = b.querySelector('.wt-num');
  10355. \t\t\t\t\t\t\t\t\t\tif (numSpan) numSpan.textContent = String(n);
  10356. \t\t\t\t\t\t\t\t\t\tb.querySelectorAll('input[name]').forEach(function(inp) {
  10357. \t\t\t\t\t\t\t\t\t\t\tinp.name = inp.name.replace(/_\\d+\$/, '_' + n);
  10358. \t\t\t\t\t\t\t\t\t\t});
  10359. \t\t\t\t\t\t\t\t\t});
  10360. \t\t\t\t\t\t\t\t}
  10361. \t\t\t\t\t\t\t\t// 軸変更イベント. recalcAll が定義されていれば再計算 (task 2 で実装).
  10362. \t\t\t\t\t\t\t\twindow.onWindowTypeAxisChange = function() {
  10363. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10364. \t\t\t\t\t\t\t\t};
  10365. \t\t\t\t\t\t\t\twindow.addWindowType = addWindowType;
  10366. \t\t\t\t\t\t\t\twindow.removeWindowType = removeWindowType;
  10367. \t\t\t\t\t\t\t\t// 隠し radio(opacity:0/pointer-events:none) を label で包む opt-btn は iOS で初回タップの
  10368. \t\t\t\t\t\t\t\t// change が不発になりやすい。窓タイプ/住宅区分は label に onclick が無く change 依存だった
  10369. \t\t\t\t\t\t\t\t// ため「2回タッチ/選択できない」が発生。click は確実に発火するので委譲 click で選択状態・
  10370. \t\t\t\t\t\t\t\t// is-selected・再計算を行う(JSで複製される窓タイプにも委譲で対応)。
  10371. \t\t\t\t\t\t\t\tdocument.addEventListener('click', function(ev) {
  10372. \t\t\t\t\t\t\t\t\tif (!ev.target || !ev.target.closest) return;
  10373. \t\t\t\t\t\t\t\t\tvar label = ev.target.closest('.opt-btn');
  10374. \t\t\t\t\t\t\t\t\tif (!label) return;
  10375. \t\t\t\t\t\t\t\t\tif (!label.closest('#window-types-container') && !label.closest('#window-housing-type-group')) return;
  10376. \t\t\t\t\t\t\t\t\tvar input = label.querySelector('input[type=\"radio\"]');
  10377. \t\t\t\t\t\t\t\t\tif (!input || input.disabled) return;
  10378. \t\t\t\t\t\t\t\t\tinput.checked = true;
  10379. \t\t\t\t\t\t\t\t\tvar nm = input.getAttribute('name');
  10380. \t\t\t\t\t\t\t\t\tif (nm) {
  10381. \t\t\t\t\t\t\t\t\t\tdocument.querySelectorAll('input[name=\"' + nm + '\"]').forEach(function(i) {
  10382. \t\t\t\t\t\t\t\t\t\t\tvar l = i.closest('.opt-btn');
  10383. \t\t\t\t\t\t\t\t\t\t\tif (l) l.classList.toggle('is-selected', i.checked);
  10384. \t\t\t\t\t\t\t\t\t\t});
  10385. \t\t\t\t\t\t\t\t\t}
  10386. \t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10387. \t\t\t\t\t\t\t\t});
  10388. \t\t\t\t\t\t\t\t// 初期表示で 1 ブロック追加 + 住宅区分ラジオの change で再計算.
  10389. \t\t\t\t\t\t\t\tdocument.addEventListener('DOMContentLoaded', function() {
  10390. \t\t\t\t\t\t\t\t\tif (document.querySelector('#window-types-container')) {
  10391. \t\t\t\t\t\t\t\t\t\taddWindowType();
  10392. \t\t\t\t\t\t\t\t\t}
  10393. \t\t\t\t\t\t\t\t\tvar housingInputs = document.querySelectorAll('input[name=\"window_housing_type\"]');
  10394. \t\t\t\t\t\t\t\t\tvar syncHousingSelectedClass = function() {
  10395. \t\t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  10396. \t\t\t\t\t\t\t\t\t\t\tvar lbl = el.closest('.opt-btn');
  10397. \t\t\t\t\t\t\t\t\t\t\tif (!lbl) return;
  10398. \t\t\t\t\t\t\t\t\t\t\tif (el.checked) lbl.classList.add('is-selected');
  10399. \t\t\t\t\t\t\t\t\t\t\telse            lbl.classList.remove('is-selected');
  10400. \t\t\t\t\t\t\t\t\t\t});
  10401. \t\t\t\t\t\t\t\t\t};
  10402. \t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  10403. \t\t\t\t\t\t\t\t\thousingInputs.forEach(function(el) {
  10404. \t\t\t\t\t\t\t\t\t\tel.addEventListener('change', function() {
  10405. \t\t\t\t\t\t\t\t\t\t\tsyncHousingSelectedClass();
  10406. \t\t\t\t\t\t\t\t\t\t\tif (typeof recalcAll === 'function') recalcAll();
  10407. \t\t\t\t\t\t\t\t\t\t});
  10408. \t\t\t\t\t\t\t\t\t});
  10409. \t\t\t\t\t\t\t\t});
  10410. \t\t\t\t\t\t\t})();
  10411. \t\t\t\t\t\t\t</script>
  10412. \t\t\t\t\t\t{% endif %}
  10413. \t\t\t\t\t\t<!-- 3: 施工見積(物置・ゴミステーション) -->
  10414. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 3 %}
  10415. \t\t\t\t\t\t\t{# 幅・奥行き・高さ(p_w/p_d/p_h からボタン型ラジオ生成) #}
  10416. \t\t\t\t\t\t\t{% if p_w and p_w|length and p_w|join != \"\" %}
  10417. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10418. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  10419. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10420. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10421. \t\t\t\t\t\t\t    {% for pw_val in p_w %}{% if pw_val %}{% set idx = idx + 1 %}
  10422. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %} is-selected{% endif %}\"
  10423. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw3_{{ idx }}');\">
  10424. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw3_{{ idx }}\" value=\"{{ pw_val }}\"
  10425. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %}checked{% endif %}>
  10426. \t\t\t\t\t\t\t        {{ pw_val }}
  10427. \t\t\t\t\t\t\t      </label>
  10428. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10429. \t\t\t\t\t\t\t  </div>
  10430. \t\t\t\t\t\t\t</div>
  10431. \t\t\t\t\t\t\t{% endif %}
  10432. \t\t\t\t\t\t\t{% if p_d and p_d|length and p_d|join != \"\" %}
  10433. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10434. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">奥行き{% if mitsumori_json and mitsumori_json.pd %}: <span>{{ mitsumori_json.pd }}</span>{% endif %}</div>
  10435. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10436. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10437. \t\t\t\t\t\t\t    {% for pd_val in p_d %}{% if pd_val %}{% set idx = idx + 1 %}
  10438. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pd == pd_val) or p_d|length == 1 %} is-selected{% endif %}\"
  10439. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pd','pd3_{{ idx }}');\">
  10440. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pd\" id=\"pd3_{{ idx }}\" value=\"{{ pd_val }}\"
  10441. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pd == pd_val) or p_d|length == 1 %}checked{% endif %}>
  10442. \t\t\t\t\t\t\t        {{ pd_val }}
  10443. \t\t\t\t\t\t\t      </label>
  10444. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10445. \t\t\t\t\t\t\t  </div>
  10446. \t\t\t\t\t\t\t</div>
  10447. \t\t\t\t\t\t\t{% endif %}
  10448. \t\t\t\t\t\t\t{% if p_h and p_h|length and p_h|join != \"\" %}
  10449. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10450. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">高さ{% if mitsumori_json and mitsumori_json.ph %}: <span>{{ mitsumori_json.ph }}</span>{% endif %}</div>
  10451. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10452. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10453. \t\t\t\t\t\t\t    {% for ph_val in p_h %}{% if ph_val %}{% set idx = idx + 1 %}
  10454. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.ph == ph_val) or p_h|length == 1 %} is-selected{% endif %}\"
  10455. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('ph','ph3_{{ idx }}');\">
  10456. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"ph\" id=\"ph3_{{ idx }}\" value=\"{{ ph_val }}\"
  10457. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.ph == ph_val) or p_h|length == 1 %}checked{% endif %}>
  10458. \t\t\t\t\t\t\t        {{ ph_val }}
  10459. \t\t\t\t\t\t\t      </label>
  10460. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10461. \t\t\t\t\t\t\t  </div>
  10462. \t\t\t\t\t\t\t</div>
  10463. \t\t\t\t\t\t\t{% endif %}
  10464. \t\t\t\t\t\t\t{# 棚タイプ(p_m データから選択肢を生成) #}
  10465. \t\t\t\t\t\t\t{% if p_m and p_m|length and p_m|join != \"\" %}
  10466. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10467. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">棚タイプ <small class=\"text-muted\">(間仕切り仕様)</small>{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  10468. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10469. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10470. \t\t\t\t\t\t\t    {% for pm_val in p_m %}{% if pm_val %}{% set idx = idx + 1 %}
  10471. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %} is-selected{% endif %}\"
  10472. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm3_{{ idx }}');\">
  10473. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm3_{{ idx }}\" value=\"{{ pm_val }}\"
  10474. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %}checked{% endif %}>
  10475. \t\t\t\t\t\t\t        {{ pm_val }}
  10476. \t\t\t\t\t\t\t      </label>
  10477. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10478. \t\t\t\t\t\t\t  </div>
  10479. \t\t\t\t\t\t\t</div>
  10480. \t\t\t\t\t\t\t{% endif %}
  10481. \t\t\t\t\t\t\t{# option1 (mo の 棚タイプ 等、p_option1 データから選択肢を生成) #}
  10482. \t\t\t\t\t\t\t{% if p_option1 and p_option1|length and p_option1|join != \"\" %}
  10483. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10484. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">{{ option1_label }}{% if mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 %}: <span>{{ mitsumori_json.option1 }}</span>{% endif %}</div>
  10485. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10486. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10487. \t\t\t\t\t\t\t    {% for opt1_val in p_option1 %}{% if opt1_val %}{% set idx = idx + 1 %}
  10488. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1_val) or p_option1|length == 1 %} is-selected{% endif %}\"
  10489. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('option1','option1_3_{{ idx }}');\">
  10490. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"option1\" id=\"option1_3_{{ idx }}\" value=\"{{ opt1_val }}\"
  10491. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.option1 is defined and mitsumori_json.option1 == opt1_val) or p_option1|length == 1 %}checked{% endif %}>
  10492. \t\t\t\t\t\t\t        {{ opt1_val }}
  10493. \t\t\t\t\t\t\t      </label>
  10494. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10495. \t\t\t\t\t\t\t  </div>
  10496. \t\t\t\t\t\t\t</div>
  10497. \t\t\t\t\t\t\t{% endif %}
  10498. \t\t\t\t\t\t\t{# カラー(共通の color データ使用) #}
  10499. \t\t\t\t\t\t\t{% if color and color|length %}
  10500. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10501. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">カラー{% if mitsumori_json and mitsumori_json.pc %}: <span>{{ mitsumori_json.pc }}</span>{% endif %}</div>
  10502. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10503. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10504. \t\t\t\t\t\t\t    {% for cc in color %}{% if cc and cc['name'] %}{% set idx = idx + 1 %}
  10505. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %} is-selected{% endif %}\"
  10506. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pc','cc3_{{ idx }}');\">
  10507. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"color3\" id=\"cc3_{{ idx }}\" value=\"{{ cc['name'] }}\"
  10508. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pc == cc['name']) or color|length == 1 %}checked{% endif %}>
  10509. \t\t\t\t\t\t\t        {{ cc['name'] }}
  10510. \t\t\t\t\t\t\t      </label>
  10511. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10512. \t\t\t\t\t\t\t  </div>
  10513. \t\t\t\t\t\t\t</div>
  10514. \t\t\t\t\t\t\t{% endif %}
  10515. \t\t\t\t\t\t\t{# 台数 #}
  10516. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10517. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">台数</label>
  10518. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10519. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  10520. \t\t\t\t\t\t\t      <input type=\"number\" name=\"daisu\" id=\"daisu\" class=\"form-control\" value=\"{{ mitsumori_json.daisu|default('1') }}\" min=\"1\" max=\"10\" onchange=\"mitsumori_simulation('daisu','daisu');\">
  10521. \t\t\t\t\t\t\t      <span class=\"input-group-text\">台</span>
  10522. \t\t\t\t\t\t\t    </div>
  10523. \t\t\t\t\t\t\t  </div>
  10524. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10525. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"daisu(+1);\">+</button>
  10526. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"daisu(-1);\">ー</button>
  10527. \t\t\t\t\t\t\t  </div>
  10528. \t\t\t\t\t\t\t</div>
  10529. \t\t\t\t\t\t{% endif %}
  10530. \t\t\t\t\t\t<!-- 4: 施工見積(フェンス・組み立て式) -->
  10531. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 4 %}
  10532. \t\t\t\t\t\t\t{# 枚数 #}
  10533. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10534. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">枚数</label>
  10535. \t\t\t\t\t\t\t  <div class=\"col-4 mb-3\">
  10536. \t\t\t\t\t\t\t    <div class=\"input-group\">
  10537. \t\t\t\t\t\t\t      <input type=\"number\" name=\"maisu\" id=\"maisu\" class=\"form-control\" value=\"{{ mitsumori_json.maisu|default('3') }}\" min=\"3\" max=\"20\" onchange=\"if(parseInt(this.value)<3)this.value=3; mitsumori_simulation('maisu','maisu');\">
  10538. \t\t\t\t\t\t\t      <span class=\"input-group-text\">枚</span>
  10539. \t\t\t\t\t\t\t    </div>
  10540. \t\t\t\t\t\t\t  </div>
  10541. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10542. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"maisu(+1);\">+</button>
  10543. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"maisu(-1);\">ー</button>
  10544. \t\t\t\t\t\t\t  </div>
  10545. \t\t\t\t\t\t\t</div>
  10546. \t\t\t\t\t\t{% endif %}
  10547. \t\t\t\t\t\t<!-- 5: 施工見積(ウッドデッキ・タイルデッキ) -->
  10548. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 5 %}
  10549. \t\t\t\t\t\t\t{# ステップの有無 #}
  10550. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10551. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">ステップ</div>
  10552. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10553. \t\t\t\t\t\t\t    {% set step_yes_checked = (mitsumori_json and mitsumori_json.deck_step is defined and mitsumori_json.deck_step == '必要') %}
  10554. \t\t\t\t\t\t\t    {% set step_no_checked = (not mitsumori_json or mitsumori_json.deck_step is not defined or mitsumori_json.deck_step == '不要' or not mitsumori_json.deck_step) %}
  10555. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if step_yes_checked %} is-selected{% endif %}\"
  10556. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_yes');\">
  10557. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_yes\" value=\"必要\"
  10558. \t\t\t\t\t\t\t             {% if step_yes_checked %}checked{% endif %}>
  10559. \t\t\t\t\t\t\t      必要
  10560. \t\t\t\t\t\t\t    </label>
  10561. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if step_no_checked %} is-selected{% endif %}\"
  10562. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op0','deck_step_no');\">
  10563. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_step\" id=\"deck_step_no\" value=\"不要\"
  10564. \t\t\t\t\t\t\t             {% if step_no_checked %}checked{% endif %}>
  10565. \t\t\t\t\t\t\t      不要
  10566. \t\t\t\t\t\t\t    </label>
  10567. \t\t\t\t\t\t\t  </div>
  10568. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-step\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not step_yes_checked %}display:none;{% endif %}\">
  10569. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  10570. \t\t\t\t\t\t\t  </div>
  10571. \t\t\t\t\t\t\t</div>
  10572. \t\t\t\t\t\t\t{# ウッドデッキフェンスの有無 #}
  10573. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10574. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">デッキフェンス</div>
  10575. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10576. \t\t\t\t\t\t\t    {% set fence_yes_checked = (mitsumori_json and mitsumori_json.deck_fence is defined and mitsumori_json.deck_fence == '必要') %}
  10577. \t\t\t\t\t\t\t    {% set fence_no_checked = (not mitsumori_json or mitsumori_json.deck_fence is not defined or mitsumori_json.deck_fence == '不要' or not mitsumori_json.deck_fence) %}
  10578. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if fence_yes_checked %} is-selected{% endif %}\"
  10579. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_yes');\">
  10580. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_yes\" value=\"必要\"
  10581. \t\t\t\t\t\t\t             {% if fence_yes_checked %}checked{% endif %}>
  10582. \t\t\t\t\t\t\t      必要
  10583. \t\t\t\t\t\t\t    </label>
  10584. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if fence_no_checked %} is-selected{% endif %}\"
  10585. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op1','deck_fence_no');\">
  10586. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"deck_fence\" id=\"deck_fence_no\" value=\"不要\"
  10587. \t\t\t\t\t\t\t             {% if fence_no_checked %}checked{% endif %}>
  10588. \t\t\t\t\t\t\t      不要
  10589. \t\t\t\t\t\t\t    </label>
  10590. \t\t\t\t\t\t\t  </div>
  10591. \t\t\t\t\t\t\t  <div class=\"opt-survey-note-wd-fence\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not fence_yes_checked %}display:none;{% endif %}\">
  10592. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  10593. \t\t\t\t\t\t\t  </div>
  10594. \t\t\t\t\t\t\t</div>
  10595. \t\t\t\t\t\t{% endif %}
  10596. \t\t\t\t\t\t<!-- 6: 施工見積(芝生・枚数・数量買い) -->
  10597. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 6 %}
  10598. \t\t\t\t\t\t\t{# 規格(p_m データ → 素材から抽出) #}
  10599. \t\t\t\t\t\t\t{% if p_m and p_m|length and p_m|join != \"\" %}
  10600. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10601. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">規格{% if mitsumori_json and mitsumori_json.pm %}: <span>{{ mitsumori_json.pm }}</span>{% endif %}</div>
  10602. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10603. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10604. \t\t\t\t\t\t\t    {% for pm_val in p_m %}{% if pm_val %}{% set idx = idx + 1 %}
  10605. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %} is-selected{% endif %}\"
  10606. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pm','pm6_{{ idx }}');\">
  10607. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pm\" id=\"pm6_{{ idx }}\" value=\"{{ pm_val }}\"
  10608. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pm == pm_val) or p_m|length == 1 %}checked{% endif %}>
  10609. \t\t\t\t\t\t\t        {{ pm_val }}
  10610. \t\t\t\t\t\t\t      </label>
  10611. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10612. \t\t\t\t\t\t\t  </div>
  10613. \t\t\t\t\t\t\t</div>
  10614. \t\t\t\t\t\t\t{% endif %}
  10615. \t\t\t\t\t\t\t{# 芝の幅(p_w = ロール幅。free_area の w。例 100cm/200cm = 1m/2m 幅。
  10616. \t\t\t\t\t\t\t   h はロール長(例 1000cm=10m)で固定のため UI には出さない)。 #}
  10617. \t\t\t\t\t\t\t{% if p_w and p_w|length and p_w|join != \"\" %}
  10618. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10619. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">芝の幅{% if mitsumori_json and mitsumori_json.pw %}: <span>{{ mitsumori_json.pw }}</span>{% endif %}</div>
  10620. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10621. \t\t\t\t\t\t\t    {% set idx = 0 %}
  10622. \t\t\t\t\t\t\t    {% for pw_val in p_w %}{% if pw_val %}{% set idx = idx + 1 %}
  10623. \t\t\t\t\t\t\t      <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %} is-selected{% endif %}\"
  10624. \t\t\t\t\t\t\t             onclick=\"mitsumori_simulation('pw','pw6_{{ idx }}');\">
  10625. \t\t\t\t\t\t\t        <input type=\"radio\" name=\"pw\" id=\"pw6_{{ idx }}\" value=\"{{ pw_val }}\"
  10626. \t\t\t\t\t\t\t               {% if (mitsumori_json and mitsumori_json.pw == pw_val) or p_w|length == 1 %}checked{% endif %}>
  10627. \t\t\t\t\t\t\t        {{ pw_val }}
  10628. \t\t\t\t\t\t\t      </label>
  10629. \t\t\t\t\t\t\t    {% endif %}{% endfor %}
  10630. \t\t\t\t\t\t\t  </div>
  10631. \t\t\t\t\t\t\t</div>
  10632. \t\t\t\t\t\t\t{% endif %}
  10633. \t\t\t\t\t\t\t{# 1ロールの長さ表記(顧客要望 #10)。h はロール長 (例 1000cm=10m) で固定のため選択ではなく表示のみ。 #}
  10634. \t\t\t\t\t\t\t{% set _roll_h = (p_h is defined and p_h|length) ? (p_h|first) : '' %}
  10635. \t\t\t\t\t\t\t{% if _roll_h %}
  10636. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10637. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">1ロールの長さ:<span style=\"font-weight:bold;\">{% if 'cm' in _roll_h %}{{ (_roll_h|replace({'cm':'', ',':''})|trim) / 100 }}m{% else %}{{ _roll_h }}{% endif %}</span></div>
  10638. \t\t\t\t\t\t\t</div>
  10639. \t\t\t\t\t\t\t{% endif %}
  10640. \t\t\t\t\t\t\t{# 施工サイズ(縦 × 横、m 入力)→ 必要枚数を自動算出して表示.
  10641. \t\t\t\t\t\t\t   面積=縦×横 を #area に流し込み、case 6 の qty=ceil(area/ロール面積) を流用. #}
  10642. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10643. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">施工サイズ</label>
  10644. \t\t\t\t\t\t\t  <div class=\"col-8\">
  10645. \t\t\t\t\t\t\t    <div class=\"input-group\">
  10646. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_len\" id=\"tf_len\"
  10647. \t\t\t\t\t\t\t        class=\"form-control\"
  10648. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_len|default('') }}\"
  10649. \t\t\t\t\t\t\t        placeholder=\"縦\" min=\"0.1\" step=\"0.1\"
  10650. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_len','tf_len');\">
  10651. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m&nbsp;×</span>
  10652. \t\t\t\t\t\t\t      <input type=\"number\" name=\"tf_wid\" id=\"tf_wid\"
  10653. \t\t\t\t\t\t\t        class=\"form-control\"
  10654. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_wid|default('') }}\"
  10655. \t\t\t\t\t\t\t        placeholder=\"横\" min=\"0.1\" step=\"0.1\"
  10656. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_wid','tf_wid');\">
  10657. \t\t\t\t\t\t\t      <span class=\"input-group-text\">m</span>
  10658. \t\t\t\t\t\t\t    </div>
  10659. \t\t\t\t\t\t\t    {# area は内部計算用に保持(縦×横を JS で書き込む) #}
  10660. \t\t\t\t\t\t\t    <input type=\"hidden\" name=\"area\" id=\"area\" value=\"{{ mitsumori_json.area|default('') }}\">
  10661. \t\t\t\t\t\t\t    {# 必要枚数は直接入力も可能。施工サイズ入力時は自動算出して上書きする。
  10662. \t\t\t\t\t\t\t       施工サイズ未入力でも、ここで枚数だけ指定してカートに入れられる。 #}
  10663. \t\t\t\t\t\t\t    <div style=\"margin-top:10px;display:inline-block;background:#fff3cd;border:1px solid #ffe69c;border-radius:6px;padding:8px 14px;font-size:16px;color:#c00;font-weight:bold;\">
  10664. \t\t\t\t\t\t\t      必要枚数:<input type=\"number\" name=\"tf_qty\" id=\"tf_qty\"
  10665. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.tf_qty|default('1') }}\" min=\"1\" step=\"1\"
  10666. \t\t\t\t\t\t\t        style=\"width:80px;font-size:22px;font-weight:bold;color:#c00;text-align:right;border:1px solid #ffe69c;border-radius:4px;padding:2px 6px;\"
  10667. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('tf_qty','tf_qty');\"> 枚
  10668. \t\t\t\t\t\t\t    </div>
  10669. \t\t\t\t\t\t\t    <div style=\"margin-top:6px;font-size:12px;color:#666;\">※ 施工サイズを入力すると必要枚数を自動計算します。サイズが分からない場合は枚数を直接ご指定ください。</div>
  10670. \t\t\t\t\t\t\t  </div>
  10671. \t\t\t\t\t\t\t</div>
  10672. \t\t\t\t\t\t{% endif %}
  10673. \t\t\t\t\t\t<!-- 7: 施工見積(数量買い・基本工事費固定) -->
  10674. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 7 %}
  10675. \t\t\t\t\t\t\t{# 個数(物置の daisu と同形式、単位は「個」) #}
  10676. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10677. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">個数</label>
  10678. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10679. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  10680. \t\t\t\t\t\t\t      <input type=\"number\" name=\"suuryou\" id=\"suuryou\" class=\"form-control\"
  10681. \t\t\t\t\t\t\t        value=\"{{ mitsumori_json.suuryou|default('1') }}\" min=\"1\" max=\"100\"
  10682. \t\t\t\t\t\t\t        onchange=\"mitsumori_simulation('suuryou','suuryou');\">
  10683. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  10684. \t\t\t\t\t\t\t    </div>
  10685. \t\t\t\t\t\t\t  </div>
  10686. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10687. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"suuryou(+1);\">+</button>
  10688. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"suuryou(-1);\">ー</button>
  10689. \t\t\t\t\t\t\t  </div>
  10690. \t\t\t\t\t\t\t</div>
  10691. \t\t\t\t\t\t{% endif %}
  10692. \t\t\t\t\t\t<!-- 9: 商品のみ購入 -->
  10693. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 9 %}
  10694. \t\t\t\t\t\t\t<div class=\"form-group row mt-2\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10695. \t\t\t\t\t\t\t  <label class=\"col-4 col-form-label\">数量</label>
  10696. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10697. \t\t\t\t\t\t\t    <div class=\"input-group mb-3\">
  10698. \t\t\t\t\t\t\t      <input type=\"number\" name=\"quantity_only\" id=\"quantity_only\" class=\"form-control\" value=\"1\" min=\"1\" onchange=\"\$('#quantity').val(this.value);\">
  10699. \t\t\t\t\t\t\t      <span class=\"input-group-text\">個</span>
  10700. \t\t\t\t\t\t\t    </div>
  10701. \t\t\t\t\t\t\t  </div>
  10702. \t\t\t\t\t\t\t  <div class=\"col-4\">
  10703. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-info\" onclick=\"quantityOnly(+1);\">+</button>
  10704. \t\t\t\t\t\t\t    <button type=\"button\" class=\"btn btn-danger\" onclick=\"quantityOnly(-1);\">ー</button>
  10705. \t\t\t\t\t\t\t  </div>
  10706. \t\t\t\t\t\t\t</div>
  10707. \t\t\t\t\t\t{% endif %}
  10708. \t\t\t\t\t    <div class=\"row\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\"><label class=\"col-12 col-form-label\">取り付け工事のご希望に関してお答えください。</label></div>
  10709. \t\t\t\t\t\t{# gs (ゴミステーション, category id=27) では「撤去対応」「残土・ガラ処理」は ex-shop に存在しないため非表示
  10710. \t\t\t\t\t\t   cg (カーゲート, category id=9) では「残土・ガラ処理」分は撤去金額側に内包済みのため非表示
  10711. \t\t\t\t\t\t   (撤去オプション自体は残す) #}
  10712. \t\t\t\t\t\t{% set is_gs = false %}
  10713. \t\t\t\t\t\t{% set is_cg = false %}
  10714. \t\t\t\t\t\t{% if Product.ProductCategories is not empty %}
  10715. \t\t\t\t\t\t\t{% for ProductCategory in Product.ProductCategories %}
  10716. \t\t\t\t\t\t\t\t{% if ProductCategory.category_id == 27 %}{% set is_gs = true %}{% endif %}
  10717. \t\t\t\t\t\t\t\t{% if ProductCategory.category_id == 9 %}{% set is_cg = true %}{% endif %}
  10718. \t\t\t\t\t\t\t{% endfor %}
  10719. \t\t\t\t\t\t{% endif %}
  10720. \t\t\t\t\t\t{% for i in 0..10 %}
  10721. \t\t\t\t\t\t\t{% if op and op|length >= i+1 %}
  10722. \t\t\t\t\t\t\t{% if op[i]['name'] %}
  10723. \t\t\t\t\t\t\t{% set hide_opt = false %}
  10724. \t\t\t\t\t\t\t{% if is_gs and (op[i]['name'] matches '/撤去/' or op[i]['name'] matches '/残土/') %}
  10725. \t\t\t\t\t\t\t\t{% set hide_opt = true %}
  10726. \t\t\t\t\t\t\t{% endif %}
  10727. \t\t\t\t\t\t\t{% if is_cg and op[i]['name'] matches '/残土/' %}
  10728. \t\t\t\t\t\t\t\t{% set hide_opt = true %}
  10729. \t\t\t\t\t\t\t{% endif %}
  10730. \t\t\t\t\t\t\t{% if not hide_opt %}
  10731. \t\t\t\t\t\t\t{# price=0 で「解体」「撤去」「設置場所」(wd 等で API 差額未提供) を含むオプションは
  10732. \t\t\t\t\t\t\t   選択時に「現場調査後に正式お見積もり」文言を出す. #}
  10733. \t\t\t\t\t\t\t{% set is_removal_unknown = (op[i]['price']|default(0) == 0 or op[i]['price']|default('0') == '0')
  10734. \t\t\t\t\t\t\t                              and (op[i]['name'] matches '/解体/' or op[i]['name'] matches '/撤去/' or op[i]['name'] matches '/設置場所/') %}
  10735. \t\t\t\t\t\t\t{# tf (人工芝, sale_type=6): ex-shop に施工価格がないため「取り付け工事も希望する」選択時に現地調査文言を表示 #}
  10736. \t\t\t\t\t\t\t{% set is_tf_kouji = (ProductClass.SaleType.id == 6 and op[i]['name'] matches '/取り付け工事/') %}
  10737. \t\t\t\t\t\t\t<div class=\"form-group mt-3 pb-3\" data-op-idx=\"{{ i }}\" data-op-name=\"{{ op[i]['name']|e('html_attr') }}\" style=\"border-bottom:1px solid rgba(0,0,0,.125)\">
  10738. \t\t\t\t\t\t\t  <div class=\"rp-section-label\">{{ op[i]['name'] }}{% if mitsumori_json and mitsumori_json.op[i] %}: <span>{{ mitsumori_json.op[i] }}</span>{% endif %}</div>
  10739. \t\t\t\t\t\t\t  {% if op[i]['comment'] %}<div class=\"opt-comment\" style=\"font-size:12px;color:#666;margin:4px 0 6px;\">{{ op[i]['comment'] }}</div>{% endif %}
  10740. \t\t\t\t\t\t\t  <div class=\"opt-btn-group\">
  10741. \t\t\t\t\t\t\t    {# off が空 (= ex-shop に選択肢が 1 つしかない基礎施工等) のときは on 側を
  10742. \t\t\t\t\t\t\t       既定選択にして 2 個目の空ラジオを描画しない. #}
  10743. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) or not op[i]['off'] %} is-selected{% endif %}\"
  10744. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op{{ i }}','op{{ i }}_1');\">
  10745. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op{{ i }}\" id=\"op{{ i }}_1\" value=\"{{ op[i]['on'] }}\" {% if (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) or not op[i]['off'] %}checked{% endif %}>
  10746. \t\t\t\t\t\t\t      {{ op[i]['on'] }}
  10747. \t\t\t\t\t\t\t    </label>
  10748. \t\t\t\t\t\t\t    {% if op[i]['off'] %}
  10749. \t\t\t\t\t\t\t    <label class=\"opt-btn{% if mitsumori_json and mitsumori_json.op[i] == op[i]['off'] %} is-selected{% endif %}\"
  10750. \t\t\t\t\t\t\t           onclick=\"mitsumori_simulation('op{{ i }}','op{{ i }}_2');\">
  10751. \t\t\t\t\t\t\t      <input type=\"radio\" name=\"op{{ i }}\" id=\"op{{ i }}_2\" value=\"{{ op[i]['off'] }}\" {% if mitsumori_json and mitsumori_json.op[i] == op[i]['off'] %}checked{% endif %}>
  10752. \t\t\t\t\t\t\t      {{ op[i]['off'] }}
  10753. \t\t\t\t\t\t\t    </label>
  10754. \t\t\t\t\t\t\t    {% endif %}
  10755. \t\t\t\t\t\t\t  </div>
  10756. \t\t\t\t\t\t\t  {% if is_removal_unknown or is_tf_kouji %}
  10757. \t\t\t\t\t\t\t  <div class=\"opt-survey-note\" data-op-idx=\"{{ i }}\" style=\"font-size:12px;color:#c00;margin-top:6px;{% if not (mitsumori_json and mitsumori_json.op[i] == op[i]['on']) %}display:none;{% endif %}\">
  10758. \t\t\t\t\t\t\t    ※ 現場調査後に正式お見積もりさせていただきます。
  10759. \t\t\t\t\t\t\t  </div>
  10760. \t\t\t\t\t\t\t  {% endif %}
  10761. \t\t\t\t\t\t\t</div>
  10762. \t\t\t\t\t\t\t{% endif %}
  10763. \t\t\t\t\t\t\t{% endif %}
  10764. \t\t\t\t\t\t\t{% endif %}
  10765. \t\t\t\t\t\t{% endfor %}
  10766. \t\t\t\t\t\t{# fe (sale_type=4) ブロックの種類×段数 サブ UI コンテナ.
  10767. \t\t\t\t\t\t   親オプション「ご希望のフェンス設置方法」 = 「新規にブロック積みを行う」
  10768. \t\t\t\t\t\t   を選択したときだけ JS (renderFeBlockRadios) で表示される. #}
  10769. \t\t\t\t\t\t{% if ProductClass.SaleType.id == 4 and oi and oi.fe_block %}
  10770. \t\t\t\t\t\t<div id=\"fe-block-options\" class=\"form-group mt-3 pb-3\" style=\"display:none;border-bottom:1px solid rgba(0,0,0,.125)\"></div>
  10771. \t\t\t\t\t\t{% endif %}
  10772. \t\t\t\t\t  </div>
  10773. \t\t\t\t\t  <!-- /.card-body -->
  10774. \t\t\t\t\t</div>
  10775.                     <form action=\"{{ url('product_add_cart', {id:Product.id}) }}\" method=\"post\" id=\"form1\" name=\"form1\">
  10776.                         {% if Product.stock_find %}
  10777.                             <div class=\"ec-productRole__actions\">
  10778.                                 {% if form.classcategory_id1 is defined %}
  10779.                                     <div class=\"ec-select\">
  10780.                                         {{ form_row(form.classcategory_id1) }}
  10781.                                         {{ form_errors(form.classcategory_id1) }}
  10782.                                     </div>
  10783.                                     {% if form.classcategory_id2 is defined %}
  10784.                                         <div class=\"ec-select\">
  10785.                                             {{ form_row(form.classcategory_id2) }}
  10786.                                             {{ form_errors(form.classcategory_id2) }}
  10787.                                         </div>
  10788.                                     {% endif %}
  10789.                                 {% endif %}
  10790.                                 <div class=\"ec-numberInput\">
  10791.                                     {{ form_widget(form.quantity, { type: 'hidden' }) }}
  10792.                                     {{ form_errors(form.quantity) }}
  10793.                                 </div>
  10794.                             </div>
  10795.                         {% else %}
  10796.                             <div class=\"ec-productRole__btn\">
  10797.                                 <button type=\"button\" class=\"ec-blockBtn--action\" disabled=\"disabled\">
  10798.                                     {{ 'ただいま品切れ中です。'|trans }}
  10799.                                 </button>
  10800.                             </div>
  10801.                         {% endif %}
  10802.                         <div class=\"ec-productRole__btn mt-3\">
  10803.                            <button type=\"submit\" id=\"cart_btn\" class=\"ec-blockBtn--action add-cart\">カートに入れる</button>
  10804.                         </div>
  10805.                         {{ form_rest(form) }}
  10806.                     </form>
  10807.                     <div class=\"ec-modal add-cart-modal\">
  10808.                         <div class=\"ec-modal-overlay\">
  10809.                             <div class=\"ec-modal-wrap add-cart-modal__wrap\">
  10810.                                 <span class=\"ec-modal-close\"><span class=\"ec-icon\"><img src=\"{{ asset('assets/icon/cross-dark.svg') }}\" alt=\"\"/></span></span>
  10811.                                 <div id=\"ec-modal-header\" class=\"text-center add-cart-modal__header\">{{ 'カートに追加しました。'|trans }}</div>
  10812.                                 <div class=\"ec-modal-box add-cart-modal__box\">
  10813.                                     <div class=\"ec-role add-cart-modal__actions\">
  10814.                                         <a href=\"{{ url('cart') }}\" class=\"ec-inlineBtn--action add-cart-modal__primary\">{{ 'カートに進む'|trans }}</a>
  10815.                                         <span class=\"ec-inlineBtn--cancel add-cart-modal__secondary\">{{ '商品検索を続ける'|trans }}</span>
  10816.                                     </div>
  10817.                                 </div>
  10818.                             </div>
  10819.                         </div>
  10820.                     </div>
  10821.                     <div class=\"ec-productRole__description\">{{ Product.description_detail|raw|nl2br }}
  10822.                     </div>
  10823.                     {# SNSシェア #}
  10824.                     <div class=\"ec-productRole__share\">
  10825.                         <ul class=\"ec-share\">
  10826.                             <li class=\"ec-share__item\">
  10827.                                 <a href=\"https://twitter.com/share?url={{ app.request.uri|url_encode }}&text={{ Product.name|url_encode }}\" class=\"ec-share__link ec-share__link--twitter\" target=\"_blank\" rel=\"noreferrer noopener\">
  10828.                                     <i class=\"fab fa-twitter\"></i>
  10829.                                 </a>
  10830.                             </li>
  10831.                             <li class=\"ec-share__item\">
  10832.                                 <a href=\"https://www.facebook.com/sharer/sharer.php?u={{ app.request.uri|url_encode }}\" class=\"ec-share__link ec-share__link--facebook\" target=\"_blank\" rel=\"noreferrer noopener\">
  10833.                                     <i class=\"fab fa-facebook-f\"></i>
  10834.                                 </a>
  10835.                             </li>
  10836.                             <li class=\"ec-share__item\">
  10837.                                 <a href=\"https://social-plugins.line.me/lineit/share?url={{ app.request.uri|url_encode }}\" class=\"ec-share__link ec-share__link--line\" target=\"_blank\" rel=\"noreferrer noopener\">
  10838.                                     <i class=\"fab fa-line\"></i>
  10839.                                 </a>
  10840.                             </li>
  10841.                         </ul>
  10842.                     </div>
  10843.                 </div>
  10844. \t\t\t\t{# ===== スマホ用 見積金額 下部固定バー ===== #}
  10845. \t\t\t\t<div id=\"sp-mitsumori-bar\">
  10846. \t\t\t\t    <div class=\"sp-bar__pricewrap\">
  10847. \t\t\t\t        <div class=\"sp-bar__label\">合計(工事費・税込)</div>
  10848. \t\t\t\t        <div class=\"sp-bar__price\" id=\"sp-mitsumori-price\">---円</div>
  10849. \t\t\t\t    </div>
  10850. \t\t\t\t    <button type=\"button\" class=\"sp-bar__btn\"
  10851. \t\t\t\t            onclick=\"document.getElementById('cart_btn2') && document.getElementById('cart_btn2').click();\">
  10852. \t\t\t\t        <i class=\"fas fa-shopping-cart\"></i>
  10853. \t\t\t\t        <span class=\"sp-bar__btn-label\">カートへ</span>
  10854. \t\t\t\t        {% set spTotalQty = get_carts_total_quantity() %}
  10855. \t\t\t\t        {% if spTotalQty > 0 %}
  10856. \t\t\t\t            <span class=\"sp-bar__cart-badge\">{{ spTotalQty|number_format }}</span>
  10857. \t\t\t\t        {% endif %}
  10858. \t\t\t\t    </button>
  10859. \t\t\t\t    <a href=\"{{ url('homepage') }}\" class=\"sp-bar__home-btn\" title=\"トップページへ\">
  10860. \t\t\t\t        <i class=\"fas fa-home\"></i>
  10861. \t\t\t\t    </a>
  10862. \t\t\t\t</div>
  10863. \t\t\t\t{# tg カテゴリ用: block 別オプション差額ラジオ (W/D 確定後に JS が動的描画) #}
  10864. \t\t\t\t<div id=\"tg-options\" class=\"tg-options-container col-12\"></div>
  10865. \t\t\t\t<div class=\"card col-12 collapsed-card sticky-top float-right mitsumori-card-pc\">
  10866. \t\t\t\t\t<div class=\"card-header\">
  10867. \t\t\t\t\t  <h3 class=\"card-title\">現在のお見積り額</h3>
  10868. \t\t\t\t\t  <div class=\"card-tools\">
  10869. \t\t\t\t\t    <span class=\"float-left\" id=\"mitsumori_message\">395000円</span>
  10870. \t\t\t\t\t    <button type=\"button\" class=\"btn btn-tool btn-mitsumori-toggle\" data-card-widget=\"collapse\" title=\"詳細を表示\">
  10871. \t\t\t\t\t      <span class=\"toggle-icon\">▼ 詳細</span>
  10872. \t\t\t\t\t    </button>
  10873. \t\t\t\t\t  </div>
  10874. \t\t\t\t\t</div>
  10875. \t\t\t\t\t<div class=\"card-body p-0\">
  10876. \t\t\t\t\t  <ul class=\"nav nav-pills flex-column\">
  10877. \t\t\t\t\t    <li class=\"nav-item active\">
  10878. \t\t\t\t\t      <a class=\"nav-link\">
  10879. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 合計(工事費・税込)
  10880. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_goukei\">395,000円</span>
  10881. \t\t\t\t\t      </a>
  10882. \t\t\t\t\t    </li>
  10883. \t\t\t\t\t    <li class=\"nav-item active\">
  10884. \t\t\t\t\t      <a class=\"nav-link\">
  10885. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 商品価格
  10886. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_price\">307,008円</span>
  10887. \t\t\t\t\t      </a>
  10888. \t\t\t\t\t    </li>
  10889. \t\t\t\t\t    {# sale_type=2 (補助金窓) ではカタログ価格軸を使わないので非表示. JS 側で #maker_price には \"---円\" を入れる. #}
  10890. \t\t\t\t\t    {% if ProductClass.SaleType.id != 2 %}
  10891. \t\t\t\t\t    <li class=\"nav-item\">
  10892. \t\t\t\t\t      <a class=\"nav-link\">
  10893. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i> カタログ価格
  10894. \t\t\t\t\t        <span class=\"float-right\" id=\"maker_price\">479,700円</span>
  10895. \t\t\t\t\t      </a>
  10896. \t\t\t\t\t    </li>
  10897. \t\t\t\t\t    {% else %}
  10898. \t\t\t\t\t    {# sale_type=2 でも JS が #maker_price を参照するので hidden で残す #}
  10899. \t\t\t\t\t    <span id=\"maker_price\" style=\"display:none;\">---円</span>
  10900. \t\t\t\t\t    {% endif %}
  10901. \t\t\t\t\t    <li class=\"nav-item\">
  10902. \t\t\t\t\t      <a class=\"nav-link\">
  10903. \t\t\t\t\t        &nbsp;&nbsp;<i class=\"far fa-file-alt\"></i>
  10904. \t\t\t\t\t        {% if ProductClass.SaleType.id == 2 %}補助金(割引額){% else %}お値引き{% endif %}
  10905. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_off\">-172,692円</span>
  10906. \t\t\t\t\t      </a>
  10907. \t\t\t\t\t    </li>
  10908. \t\t\t\t\t    {# 補助金窓のみ: 当店が申請代行する旨を補助金行の直下に小さく表示 (消費者の手続き勘違い防止) #}
  10909. \t\t\t\t\t    {% if ProductClass.SaleType.id == 2 %}
  10910. \t\t\t\t\t    <li class=\"nav-item\">
  10911. \t\t\t\t\t      <div style=\"padding:4px 12px 8px;color:#6c757d;font-size:11px;line-height:1.4;\">
  10912. \t\t\t\t\t        ※当店が補助金事業者として申請代行し、契約代金に充当します
  10913. \t\t\t\t\t      </div>
  10914. \t\t\t\t\t    </li>
  10915. \t\t\t\t\t    {% endif %}
  10916. \t\t\t\t\t    <li class=\"nav-item\">
  10917. \t\t\t\t\t      <a class=\"nav-link\">
  10918. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 基本工事費
  10919. \t\t\t\t\t        <span class=\"float-right\" id=\"mitsumori_ct\">53,250円</span>
  10920. \t\t\t\t\t      </a>
  10921. \t\t\t\t\t    </li>
  10922. \t\t\t\t\t    <li class=\"nav-item\">
  10923. \t\t\t\t\t      <a class=\"nav-link\">
  10924. \t\t\t\t\t        <i class=\"far fa-file-alt\"></i> 施工オプション
  10925. \t\t\t\t\t        <span class=\"float-right\"id=\"mitsumori_option\">6,297円</span>
  10926. \t\t\t\t\t      </a>
  10927. \t\t\t\t\t    </li>
  10928. \t\t\t\t\t  </ul>
  10929. \t\t\t\t\t</div>
  10930. \t\t\t\t\t<div class=\"card-footer\">
  10931. \t\t                <button type=\"button\" id=\"mitsumori_btn\" class=\"btn btn-info\" data-toggle=\"modal\" data-target=\"#modal-mitsumori\">
  10932. \t\t                  見積書表示
  10933. \t\t                </button>
  10934.                         <button type=\"submit\" id=\"cart_btn2\" class=\"btn btn-info add-cart\">カートに入れる</button>
  10935. \t\t\t\t\t</div>
  10936. \t\t\t\t</div>
  10937.             </div>
  10938.         </div>
  10939.     </div>
  10940.   <div class=\"modal\" id=\"modal-mitsumori\">
  10941.     <div class=\"modal-dialog modal-mitsumori\" style=\"max-width:1000px\">
  10942.       <div class=\"modal-content\">
  10943.         <div class=\"modal-header\">
  10944.           <h4 class=\"modal-title\">お見積書</h4>
  10945.           <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">
  10946.             <span aria-hidden=\"true\">&times;</span>
  10947.           </button>
  10948.         </div>
  10949.         <div class=\"modal-body\">
  10950. \t\t\t<div class=\"invoice p-3 mb-5\" style=\"max-width:1000px; margin:auto;\">
  10951. \t\t\t  <!-- title row -->
  10952. \t\t\t  <div class=\"row\">
  10953. \t\t\t    <div class=\"col-12\">
  10954. \t\t\t      <h2>概算お見積書 
  10955. \t\t\t        <small class=\"float-right\" style=\"font-size:14px;\">発行日: 2025/03/14</small>
  10956. \t\t\t      </h2>
  10957. \t\t\t    </div>
  10958. \t\t\t    <!-- /.col -->
  10959. \t\t\t  </div>
  10960. \t\t\t  <!-- info row -->
  10961. \t\t\t  <div class=\"row invoice-info\">
  10962. \t\t\t    <div class=\"col-sm-8 invoice-col\">
  10963. \t\t\t      <h3>お客様</h3>
  10964. \t\t\t      <span>下記の通り、お見積もり申し上げます。</span>
  10965. \t\t\t      <br />
  10966. \t\t\t      <br / >
  10967. \t\t\t      <br />
  10968. \t\t\t      <h2>お見積金額: <span id=\"mitsumori_kei\">399,080円</span></h2>
  10969. \t\t\t      <span>
  10970. \t\t\t        <br/>
  10971. \t\t\t        <br/>
  10972. \t\t\t        <br/>
  10973. \t\t\t        <br/>
  10974. \t\t\t      </span>
  10975. \t\t\t    </div>
  10976. \t\t\t    <div class=\"col-sm-4 invoice-col\">
  10977. \t\t\t      <p>
  10978. \t\t\t        <img alt=\"\" src=\"/html/user_data/js/images/logo.png\" style=\"width: 260px; max-width: 100%; max-height: 10mm;\">
  10979. \t\t\t      </p>
  10980. \t\t\t      <p>有限会社プラス</p>
  10981. \t\t\t      <p>〒400-0334</p>
  10982. \t\t\t      <p>山梨県南アルプス市藤田1450番地2</p>
  10983. \t\t\t      <p>TEL: 055-284-6480</p>
  10984. \t\t\t      <img alt=\"\" src=\"/html/user_data/js/images/seal.svg\" style=\"z-index: 2; position: absolute; width: 21mm; left: 58mm; top: 36mm;\">
  10985. \t\t\t    </div>
  10986. \t\t\t    <!-- /.col -->
  10987. \t\t\t    <!-- /.col -->
  10988. \t\t\t  </div>
  10989. \t\t\t  <!-- /.row -->
  10990. \t\t\t  <!-- Table row -->
  10991. \t\t\t  <div class=\"row\">
  10992. \t\t\t    <div class=\"col-12 table-responsive\">
  10993. \t\t\t      <table class=\"table table-striped\">
  10994. \t\t\t        <thead>
  10995. \t\t\t          <tr>
  10996. \t\t\t            <th>項目</th>
  10997. \t\t\t            <th>数量</th>
  10998. \t\t\t            <th>単位</th>
  10999. \t\t\t            <th>単価</th>
  11000. \t\t\t            <th>小計</th>
  11001. \t\t\t          </tr>
  11002. \t\t\t        </thead>
  11003. \t\t\t        <tbody>
  11004. \t\t\t          <tr>
  11005. \t\t\t            <td id=\"mitsumori_item_name\">{{ Product.name }}</td>
  11006. \t\t\t            <td>1</td>
  11007. \t\t\t            <td>式</td>
  11008. \t\t\t            <td id=\"mitsumori_price_01\">352,800</td>
  11009. \t\t\t            <td id=\"mitsumori_price_02\">352,800</td>
  11010. \t\t\t          </tr>
  11011. \t\t\t          <tr>
  11012. \t\t\t            <td>基本工事費</td>
  11013. \t\t\t            <td>1</td>
  11014. \t\t\t            <td>式</td>
  11015. \t\t\t            <td id=\"mitsumori_ct_01\">10,000</td>
  11016. \t\t\t            <td id=\"mitsumori_ct_02\">10,000</td>
  11017. \t\t\t          </tr>
  11018. \t\t\t          <tr>
  11019. \t\t\t            <td>残土・ガラ処理</td>
  11020. \t\t\t            <td>1</td>
  11021. \t\t\t            <td>式</td>
  11022. \t\t\t            <td>0円</td>
  11023. \t\t\t            <td></td>
  11024. \t\t\t          </tr>
  11025. \t\t\t          <tr>
  11026. \t\t\t            <td> </td>
  11027. \t\t\t            <td></td>
  11028. \t\t\t            <td></td>
  11029. \t\t\t            <td></td>
  11030. \t\t\t            <td></td>
  11031. \t\t\t          </tr>
  11032. \t\t\t        </tbody>
  11033. \t\t\t      </table>
  11034. \t\t\t    </div>
  11035. \t\t\t    <!-- /.col -->
  11036. \t\t\t  </div>
  11037. \t\t\t  <!-- /.row -->
  11038. \t\t\t  <div class=\"row\">
  11039. \t\t\t    <!-- accepted payments column -->
  11040. \t\t\t    <div class=\"col-6\">
  11041. \t\t\t      <p class=\"lead\">お支払い方法</p>
  11042. \t\t\t      <p class=\"text-muted well well-sm shadow-none\" style=\"margin-top: 10px;\">銀行振込、クレジットカード決済、PAYPAY決済
  11043. \t\t\t        <br>銀行振込:山梨中央銀行 白根支店 普通口座 391402
  11044. \t\t\t        <br>※商品代金と工事代金の総額が金100万円(税込)を超える場合、着手金として代金の半額をご契約後お支払いいただきます。 
  11045. \t\t\t      </p>
  11046. \t\t\t    </div>
  11047. \t\t\t    <!-- /.col -->
  11048. \t\t\t    <div class=\"col-6\">
  11049. \t\t\t      <div class=\"table-responsive\">
  11050. \t\t\t        <table class=\"table\">
  11051. \t\t\t          <tbody>
  11052. \t\t\t            <tr>
  11053. \t\t\t              <th style=\"width:50%\">小計:</th>
  11054. \t\t\t              <td id=\"mitsumori_shoukei\">362,800</td>
  11055. \t\t\t            </tr>
  11056. \t\t\t            <tr>
  11057. \t\t\t              <th>消費税 (10%)</th>
  11058. \t\t\t              <td id=\"mitsumori_tax\">36,280</td>
  11059. \t\t\t            </tr>
  11060. \t\t\t            <tr>
  11061. \t\t\t              <th>合計:</th>
  11062. \t\t\t              <td id=\"mitsumori_goukei_02\">399,080</td>
  11063. \t\t\t            </tr>
  11064. \t\t\t          </tbody>
  11065. \t\t\t        </table>
  11066. \t\t\t      </div>
  11067. \t\t\t    </div>
  11068. \t\t\t    <!-- /.col -->
  11069. \t\t\t  </div>
  11070. \t\t\t  <!-- /.row -->
  11071. \t\t\t</div>
  11072.         </div>
  11073.         <div class=\"modal-footer justify-content-between\">
  11074. \t\t\t      {# PDF出力: mitsumori_json を POST して PDF ダウンロード #}
  11075. \t\t\t      <form method=\"post\" action=\"{{ url('mitsumori_pdf') }}\" target=\"_blank\" id=\"pdf_download_form\">
  11076. \t\t\t        <input type=\"hidden\" name=\"_token\" value=\"{{ csrf_token('mitsumori_pdf') }}\">
  11077. \t\t\t        <input type=\"hidden\" name=\"mitsumori_json\" id=\"pdf_mitsumori_json\">
  11078. \t\t\t        <button type=\"submit\" class=\"btn btn-primary float-right\" style=\"margin-right: 5px;\" onclick=\"syncPdfJson();\">
  11079. \t\t\t          <i class=\"fas fa-download\"></i>PDF出力
  11080. \t\t\t        </button>
  11081. \t\t\t      </form>
  11082.                   <button type=\"submit\" id=\"cart_btn3\" class=\"btn btn-info add-cart\">カートに入れる</button>
  11083.         </div>
  11084.       </div>
  11085.       <!-- /.modal-content -->
  11086.     </div>
  11087.     <!-- /.modal-dialog -->
  11088.   </div>
  11089.   <!-- /.modal -->
  11090.     <!-- Image zoom modal: custom lightweight lightbox (no CDN dependency) -->
  11091.     <div id=\"img-modal\" role=\"dialog\" aria-modal=\"true\" aria-label=\"画像拡大\">
  11092.         <button id=\"img-modal__close\" aria-label=\"閉じる\">&times;</button>
  11093.         <button id=\"img-modal__prev\" aria-label=\"前の画像\">&#10094;</button>
  11094.         <img id=\"img-modal__img\" src=\"\" alt=\"\">
  11095.         <button id=\"img-modal__next\" aria-label=\"次の画像\">&#10095;</button>
  11096.     </div>
  11097.     <style>
  11098.     #img-modal {
  11099.         display: none;
  11100.         position: fixed;
  11101.         inset: 0;
  11102.         z-index: 9999;
  11103.         background: rgba(0,0,0,0.88);
  11104.         align-items: center;
  11105.         justify-content: center;
  11106.         cursor: zoom-out;
  11107.     }
  11108.     #img-modal.is-open { display: flex; }
  11109.     #img-modal__img {
  11110.         max-width: 92vw;
  11111.         max-height: 88vh;
  11112.         object-fit: contain;
  11113.         border-radius: 4px;
  11114.         cursor: default;
  11115.         user-select: none;
  11116.         touch-action: pinch-zoom;
  11117.         display: block;
  11118.     }
  11119.     #img-modal__close {
  11120.         position: absolute;
  11121.         top: 14px;
  11122.         right: 18px;
  11123.         font-size: 38px;
  11124.         color: #fff;
  11125.         cursor: pointer;
  11126.         background: none;
  11127.         border: none;
  11128.         padding: 0;
  11129.         line-height: 1;
  11130.         z-index: 1;
  11131.         opacity: 0.85;
  11132.     }
  11133.     #img-modal__close:hover { opacity: 1; }
  11134.     #img-modal__prev,
  11135.     #img-modal__next {
  11136.         position: absolute;
  11137.         top: 50%;
  11138.         transform: translateY(-50%);
  11139.         font-size: 36px;
  11140.         color: #fff;
  11141.         cursor: pointer;
  11142.         background: rgba(0,0,0,0.32);
  11143.         border: none;
  11144.         padding: 10px 16px;
  11145.         line-height: 1;
  11146.         border-radius: 6px;
  11147.         z-index: 1;
  11148.         opacity: 0.8;
  11149.         user-select: none;
  11150.     }
  11151.     #img-modal__prev:hover, #img-modal__next:hover { opacity: 1; }
  11152.     #img-modal__prev { left: 12px; }
  11153.     #img-modal__next { right: 12px; }
  11154.     @media (max-width: 767px) {
  11155.         #img-modal__prev, #img-modal__next { font-size: 28px; padding: 8px 12px; }
  11156.     }
  11157.     </style>
  11158.     <script>
  11159.     (function(){
  11160.         var images = [];
  11161.         var current = 0;
  11162.         // Collect original (non-cloned) slide images at click time.
  11163.         // After Slick init, slides are wrapped in .slick-slide; clones have .slick-cloned.
  11164.         function collectImages() {
  11165.             images = [];
  11166.             var \$slides = \$('.item_visual .slick-slide:not(.slick-cloned)');
  11167.             if (!\$slides.length) {
  11168.                 // Slick not yet initialized (fallback)
  11169.                 \$slides = \$('.item_visual .slide-item');
  11170.             }
  11171.             \$slides.each(function() {
  11172.                 var \$a = \$(this).find('a.js-zoom');
  11173.                 if (\$a.length) {
  11174.                     images.push({ src: \$a.attr('href'), alt: \$a.find('img').attr('alt') || '' });
  11175.                 }
  11176.             });
  11177.         }
  11178.         function showImage(idx) {
  11179.             current = ((idx % images.length) + images.length) % images.length;
  11180.             \$('#img-modal__img').attr({ src: images[current].src, alt: images[current].alt });
  11181.         }
  11182.         function openModal(href) {
  11183.             collectImages();
  11184.             if (!images.length) return;
  11185.             var idx = 0;
  11186.             for (var i = 0; i < images.length; i++) {
  11187.                 if (images[i].src === href) { idx = i; break; }
  11188.             }
  11189.             showImage(idx);
  11190.             \$('#img-modal').addClass('is-open');
  11191.             \$('body').css('overflow', 'hidden');
  11192.         }
  11193.         function closeModal() {
  11194.             \$('#img-modal').removeClass('is-open');
  11195.             \$('body').css('overflow', '');
  11196.         }
  11197.         // Click handler: works for both original and Slick-cloned anchors
  11198.         \$(document).on('click', '.item_visual a.js-zoom', function(e) {
  11199.             e.preventDefault();
  11200.             openModal(\$(this).attr('href'));
  11201.         });
  11202.         // Close on backdrop click
  11203.         \$('#img-modal').on('click', function(e) {
  11204.             if (e.target === this) closeModal();
  11205.         });
  11206.         \$('#img-modal__close').on('click', closeModal);
  11207.         \$('#img-modal__prev').on('click', function(e) { e.stopPropagation(); showImage(current - 1); });
  11208.         \$('#img-modal__next').on('click', function(e) { e.stopPropagation(); showImage(current + 1); });
  11209.         // Keyboard navigation
  11210.         \$(document).on('keydown', function(e) {
  11211.             if (!\$('#img-modal').hasClass('is-open')) return;
  11212.             if (e.key === 'Escape') closeModal();
  11213.             if (e.key === 'ArrowLeft') showImage(current - 1);
  11214.             if (e.key === 'ArrowRight') showImage(current + 1);
  11215.         });
  11216.         // Touch swipe (horizontal only)
  11217.         var _tx = 0;
  11218.         var \$modal = document.getElementById('img-modal');
  11219.         \$modal.addEventListener('touchstart', function(e) {
  11220.             _tx = e.changedTouches[0].clientX;
  11221.         }, { passive: true });
  11222.         \$modal.addEventListener('touchend', function(e) {
  11223.             var dx = e.changedTouches[0].clientX - _tx;
  11224.             if (Math.abs(dx) > 48) {
  11225.                 dx < 0 ? showImage(current + 1) : showImage(current - 1);
  11226.             }
  11227.         }, { passive: true });
  11228.     })();
  11229.     </script>
  11230. {% endblock %}
  11231. ""Product/detail.twig""/home/xs538259/exterior-plus.jp/public_html/app/template/default/Product/detail.twig");
  11232.     }
  11233. }