starting with integration of js-cardgame
This commit is contained in:
		@@ -1,14 +1,17 @@
 | 
				
			|||||||
# noinspection PyUnresolvedReferences
 | 
					# noinspection PyUnresolvedReferences
 | 
				
			||||||
from app_instance import api
 | 
					from app_instance import api
 | 
				
			||||||
# noinspection PyUnresolvedReferences
 | 
					# noinspection PyUnresolvedReferences
 | 
				
			||||||
from views.api_views import *
 | 
					 | 
				
			||||||
# noinspection PyUnresolvedReferences
 | 
					 | 
				
			||||||
from views.home import *
 | 
					from views.home import *
 | 
				
			||||||
# noinspection PyUnresolvedReferences
 | 
					# noinspection PyUnresolvedReferences
 | 
				
			||||||
from views.temp_css import *
 | 
					from views.temp_css import *
 | 
				
			||||||
# noinspection PyUnresolvedReferences
 | 
					# noinspection PyUnresolvedReferences
 | 
				
			||||||
from views.player import *
 | 
					from views.player import *
 | 
				
			||||||
# noinspection PyUnresolvedReferences
 | 
					# noinspection PyUnresolvedReferences
 | 
				
			||||||
 | 
					from views.gplayer import *
 | 
				
			||||||
 | 
					# noinspection PyUnresolvedReferences
 | 
				
			||||||
 | 
					from views.js_cardgame import *
 | 
				
			||||||
 | 
					# noinspection PyUnresolvedReferences
 | 
				
			||||||
from views.control import *
 | 
					from views.control import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
api.add_route("/static", static=True)
 | 
					api.add_route("/static", static=True)
 | 
				
			||||||
 | 
					api.add_route("/js", static=True)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										186
									
								
								templates/home/gplayer.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								templates/home/gplayer.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,186 @@
 | 
				
			|||||||
 | 
					{% extends "/shared/_layout.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <script>
 | 
				
			||||||
 | 
					        function playCard(card) {
 | 
				
			||||||
 | 
					            let player = {{player}}
 | 
				
			||||||
 | 
					            window.game_socket.send("playcard "+player+":"+card)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function setTrumpColor(color) {
 | 
				
			||||||
 | 
					            let player = {{player}}
 | 
				
			||||||
 | 
					            window.game_socket.send("setTrumpColor "+player+":"+color)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        </script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div style="font-family:Wizzta; font-size:100px"></div>
 | 
				
			||||||
 | 
					        <div class="content">
 | 
				
			||||||
 | 
					            <script src="/js-cardgame/pixi.min.js"></script>
 | 
				
			||||||
 | 
					            <script src="/js-cardgame/js/card.js"></script>
 | 
				
			||||||
 | 
					            <script src="/js-cardgame/js/carddeck.js"></script>
 | 
				
			||||||
 | 
					            <script src="/js-cardgame/js/player.js"></script>
 | 
				
			||||||
 | 
					            <script src="/js-cardgame/js/game.js"></script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let game = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					window.onload = function()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PIXI.AbstractRenderer.autoDensity = true;
 | 
				
			||||||
 | 
					    let app = new PIXI.Application();
 | 
				
			||||||
 | 
					    app.renderer.view.style.position = "absolute";
 | 
				
			||||||
 | 
					    app.renderer.view.style.display = "block";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function resize()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        let width = 1920;
 | 
				
			||||||
 | 
					        let height = 1080;
 | 
				
			||||||
 | 
					        let w = window.innerWidth;
 | 
				
			||||||
 | 
					        let h = window.innerHeight;
 | 
				
			||||||
 | 
					        let scale = Math.min(w/width, h/height)
 | 
				
			||||||
 | 
					        app.stage.scale.x = scale;
 | 
				
			||||||
 | 
					        app.stage.scale.y = scale;
 | 
				
			||||||
 | 
					        app.renderer.resize(w, h);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function addResources(loader)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        loader.add("mask", "https://www.denkmair.de/wizard-pixi/deck/mask.png");
 | 
				
			||||||
 | 
					        loader.add("back", "https://www.denkmair.de/wizard-pixi/deck/back1.jpg");
 | 
				
			||||||
 | 
					        for (let i = 0; i < 14; i++) {
 | 
				
			||||||
 | 
					            ["r", "g", "b", "y"].forEach(function (c) {
 | 
				
			||||||
 | 
					                let name = c + ((i < 10) ? "0" + i : i);
 | 
				
			||||||
 | 
					                loader.add(name, "https://www.denkmair.de/wizard-pixi/deck/" + name + ".jpg");
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (let i = 1; i < 5; i++) {
 | 
				
			||||||
 | 
					            loader.add("z" + i, "https://www.denkmair.de/wizard-pixi/deck/z" + i + ".jpg");
 | 
				
			||||||
 | 
					            loader.add("n" + i, "https://www.denkmair.de/wizard-pixi/deck/n" + i + ".jpg");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resize();
 | 
				
			||||||
 | 
					    window.addEventListener("resize", resize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    app.renderer.backgroundColor = 0x222222;
 | 
				
			||||||
 | 
					    document.body.appendChild(app.view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let loader = PIXI.Loader.shared;
 | 
				
			||||||
 | 
					    addResources(loader);
 | 
				
			||||||
 | 
					    loader.load(function(loader, resources)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        game = new Game(app.stage, resources);
 | 
				
			||||||
 | 
					        game.init(['Hubert', 'Struppi', 'Patrice', 'Steffi', "Max", "Renate"]);
 | 
				
			||||||
 | 
					        game.give_round(["z3", "b04", "r08", "g12", "y13", "r02", "b05", "b02", "b03", "g03", "g05"]);
 | 
				
			||||||
 | 
					        game.play_card(0, 0, "z3");
 | 
				
			||||||
 | 
					        game.play_card(1, 0, "y13");
 | 
				
			||||||
 | 
					        game.play_card(2, 0, "b02");
 | 
				
			||||||
 | 
					        game.play_card(3, 0, "r02");
 | 
				
			||||||
 | 
					        game.play_card(4, 0, "y05");
 | 
				
			||||||
 | 
					        game.play_card(5, 0, "g05");
 | 
				
			||||||
 | 
					        game.give_trick_to(0);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!--        <div class="content">
 | 
				
			||||||
 | 
					            <h1><span class="font-semi-bold">Gambling Foo</span> <span class="smaller">A RESTful gaming service</span></h1>
 | 
				
			||||||
 | 
					            <p class="lead">
 | 
				
			||||||
 | 
					                Play a nice game of cards?<br>
 | 
				
			||||||
 | 
					                <br>
 | 
				
			||||||
 | 
					                <strong>Player {{player+1}} view</strong><br>
 | 
				
			||||||
 | 
					                <strong> Table </strong><br>
 | 
				
			||||||
 | 
					                {% for player,card in played_cards %}
 | 
				
			||||||
 | 
					                  ||
 | 
				
			||||||
 | 
					                  {{player.name}}: {{card}}
 | 
				
			||||||
 | 
					                {% endfor %}
 | 
				
			||||||
 | 
					                ||
 | 
				
			||||||
 | 
					                <br>
 | 
				
			||||||
 | 
					                <sub>
 | 
				
			||||||
 | 
					                <strong>Tricks:</strong>
 | 
				
			||||||
 | 
					                {% for player,_ in last_trick %}
 | 
				
			||||||
 | 
					                  ||
 | 
				
			||||||
 | 
					                  {{player.name}}: {{player.tricks_taken}}
 | 
				
			||||||
 | 
					                {% endfor %}
 | 
				
			||||||
 | 
					                ||
 | 
				
			||||||
 | 
					                <br>
 | 
				
			||||||
 | 
					                <strong>Last Trick:</strong>
 | 
				
			||||||
 | 
					                {% for player,card in last_trick %}
 | 
				
			||||||
 | 
					                  ||
 | 
				
			||||||
 | 
					                  {{player.name}}: {{card}}
 | 
				
			||||||
 | 
					                {% endfor %}
 | 
				
			||||||
 | 
					                ||
 | 
				
			||||||
 | 
					                </sub>
 | 
				
			||||||
 | 
					                <br>
 | 
				
			||||||
 | 
					                <strong> Your cards: </strong>
 | 
				
			||||||
 | 
					            <ul>
 | 
				
			||||||
 | 
					                <li>
 | 
				
			||||||
 | 
					                    <strong>Trump Card: {{trump_card}}</strong><br>
 | 
				
			||||||
 | 
					                    <strong>Trump Color: {{trump_color}}</strong><br>
 | 
				
			||||||
 | 
					                </li>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                {% for card in cards %}
 | 
				
			||||||
 | 
					                    <li>
 | 
				
			||||||
 | 
					                        <strong>>card {{loop.index}} is: {{card}} </strong><br>
 | 
				
			||||||
 | 
					                         {% if playerActive and not choose_trump_color %}
 | 
				
			||||||
 | 
					                            <!–
 | 
				
			||||||
 | 
					                            <a href="/player/{{player}}/play/{{loop.index0}}">play card {{loop.index}}<{{card}}></a>
 | 
				
			||||||
 | 
					                            <div style="background-color:#D94A38;width:170px;height:80px;margin:20px;padding-top:20px;color:#ffffff;font-weight:bold;font-size:18px;float:left;text-align:center;" onclick="playCard({{loop.index0}})">Play Me</div>
 | 
				
			||||||
 | 
					                            –>
 | 
				
			||||||
 | 
					                        <button onclick="playCard({{loop.index0}})">Play {{card}}</button>
 | 
				
			||||||
 | 
					                        {% endif %}
 | 
				
			||||||
 | 
					                    </li>
 | 
				
			||||||
 | 
					                {% endfor %}
 | 
				
			||||||
 | 
					                {% if choose_trump_color and (player == choose_trump_player) %}
 | 
				
			||||||
 | 
					                <strong>Choose Trump Color:</strong>
 | 
				
			||||||
 | 
					                <!–
 | 
				
			||||||
 | 
					                <a href="/player/{{player}}/set_trump/r">Red></a>
 | 
				
			||||||
 | 
					                <a href="/player/{{player}}/set_trump/g">Green></a>
 | 
				
			||||||
 | 
					                <a href="/player/{{player}}/set_trump/b">Blue></a>
 | 
				
			||||||
 | 
					                <a href="/player/{{player}}/set_trump/y">Yellow ></a>
 | 
				
			||||||
 | 
					                –>
 | 
				
			||||||
 | 
					                <button onclick="setTrumpColor('r')">Red</button>
 | 
				
			||||||
 | 
					                <button onclick="setTrumpColor('g')">Green</button>
 | 
				
			||||||
 | 
					                <button onclick="setTrumpColor('b')">Blue</button>
 | 
				
			||||||
 | 
					                <button onclick="setTrumpColor('y')">Yellow</button>
 | 
				
			||||||
 | 
					                {% endif %}
 | 
				
			||||||
 | 
					            <!–
 | 
				
			||||||
 | 
					                <li>
 | 
				
			||||||
 | 
					                    <strong>Movie by IMDB code</strong><br>
 | 
				
			||||||
 | 
					                    <a href="/api/movie/tt0096754">GET /api/movie/{imdb_number}</a>
 | 
				
			||||||
 | 
					                </li>
 | 
				
			||||||
 | 
					                <li>
 | 
				
			||||||
 | 
					                    <strong>Top 10 Movies (by IMDB score)</strong><br>
 | 
				
			||||||
 | 
					                    <a href="/api/movie/top">GET /api/movie/top</a>
 | 
				
			||||||
 | 
					                </li>
 | 
				
			||||||
 | 
					                <li>
 | 
				
			||||||
 | 
					                    <strong>All genres</strong><br>
 | 
				
			||||||
 | 
					                    <a href="/api/movie/genre/all">GET /api/movie/genre/all</a>
 | 
				
			||||||
 | 
					                </li>
 | 
				
			||||||
 | 
					                <li>
 | 
				
			||||||
 | 
					                    <strong>Top movies for a given genres</strong><br>
 | 
				
			||||||
 | 
					                    <a href="/api/movie/genre/sci-fi">GET /api/movie/genre/{genre}</a>
 | 
				
			||||||
 | 
					                </li>
 | 
				
			||||||
 | 
					–>
 | 
				
			||||||
 | 
					            </ul>
 | 
				
			||||||
 | 
					            </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <p class="disclaimer">
 | 
				
			||||||
 | 
					                Spam Bacon Sausage + Spam
 | 
				
			||||||
 | 
					                Spam Spam Spam Spam Spam
 | 
				
			||||||
 | 
					                  Spam Baked Beans Spam
 | 
				
			||||||
 | 
					                  Spam Spam + Spam
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </p>
 | 
				
			||||||
 | 
					        </div>-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
@@ -55,6 +55,19 @@
 | 
				
			|||||||
            alert("[error]: "+error.message);
 | 
					            alert("[error]: "+error.message);
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    </script>
 | 
					    </script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!--
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        * {padding: 0; margin: 0}
 | 
				
			||||||
 | 
					        @font-face {
 | 
				
			||||||
 | 
					            font-family: "Wizzta";
 | 
				
			||||||
 | 
					            src: url("/js-cardgame/wizzta-vada-webfont.woff2") format("woff2"),
 | 
				
			||||||
 | 
					                 url("/js-cardgame/wizzta-vada-webfont.woff") format("woff");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
@@ -94,7 +107,7 @@
 | 
				
			|||||||
<!-- Bootstrap core JavaScript
 | 
					<!-- Bootstrap core JavaScript
 | 
				
			||||||
================================================== -->
 | 
					================================================== -->
 | 
				
			||||||
<!-- Placed at the end of the document so the pages load faster -->
 | 
					<!-- Placed at the end of the document so the pages load faster -->
 | 
				
			||||||
<script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script>
 | 
					<!-- <script src="https://oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> -->
 | 
				
			||||||
<script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
 | 
					<script src="/js-cardgame/jquery-3.5.1.min.js"></script>
 | 
				
			||||||
 | 
					<script src="https://oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
@@ -1,39 +0,0 @@
 | 
				
			|||||||
from responder import Response
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from app_instance import api
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
response_count_max = 10
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@api.route("/api/search/{keyword}")
 | 
					 | 
				
			||||||
def search_keyword(req, resp, keyword: str):
 | 
					 | 
				
			||||||
    resp.media = {'keyword': keyword, 'hits': "movie_dicts", 'truncated_results': "limited"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@api.route("/api/director/{director_name}")
 | 
					 | 
				
			||||||
def search_director(_, resp, director_name: str):
 | 
					 | 
				
			||||||
    resp.media = {'keyword': director_name, 'hits': "movies_dicts", 'truncated_results': "limited"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@api.route("/api/movie/genre/{genre}")
 | 
					 | 
				
			||||||
def movies_by_genre(_, resp: Response, genre: str):
 | 
					 | 
				
			||||||
    resp.media = {'genre': genre, 'hits': "hits_dicts", 'truncated_results': "limited"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@api.route("/api/movie/{imdb_number}")
 | 
					 | 
				
			||||||
def search_imdb(_, resp, imdb_number: str):
 | 
					 | 
				
			||||||
    resp.media = {'foo': "bar"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@api.route("/api/movie/top")
 | 
					 | 
				
			||||||
def top_movies(_, resp: Response):
 | 
					 | 
				
			||||||
    resp.media = {'keyword': "keyword", 'hits': "hits_dicts", 'truncated_results': "limited"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@api.route("/api/movie/genre/all")
 | 
					 | 
				
			||||||
def all_genres(_, resp: Response):
 | 
					 | 
				
			||||||
    resp.media = {"all": "stuff"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@api.route("/api/shuffle")
 | 
					 | 
				
			||||||
def cards_shuffle(_, resp: Response):
 | 
					 | 
				
			||||||
    resp.media = {"shuffled": "done"}
 | 
					 | 
				
			||||||
							
								
								
									
										29
									
								
								views/gplayer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								views/gplayer.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					from app_instance import api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from wiz_game import the_game
 | 
				
			||||||
 | 
					from starlette.websockets import WebSocketDisconnect
 | 
				
			||||||
 | 
					import asyncio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# don't define here, it's defined elsewhere!
 | 
				
			||||||
 | 
					#playing_lock = asyncio.Lock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@api.route("/gplayer/{player}")
 | 
				
			||||||
 | 
					def show(req, resp, player: str):
 | 
				
			||||||
 | 
					    p = int(player)
 | 
				
			||||||
 | 
					    tcard = the_game.trump_card
 | 
				
			||||||
 | 
					    tcolor = the_game.get_trump_color()
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        isActive = the_game.players_ordered[the_game.active_player].id == p
 | 
				
			||||||
 | 
					    except IndexError:
 | 
				
			||||||
 | 
					        isActive = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    prev_player = the_game.get_prev_player()
 | 
				
			||||||
 | 
					    if tcard and tcard.value == 'Z' and tcolor == '-':
 | 
				
			||||||
 | 
					        choose_trump_color = True
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        choose_trump_color = False
 | 
				
			||||||
 | 
					    resp.content = api.template('home/gplayer.html', player=p, playerActive=isActive, choose_trump_player=prev_player,
 | 
				
			||||||
 | 
					                                cards=the_game.players[p].cards, choose_trump_color=choose_trump_color,
 | 
				
			||||||
 | 
					                                trump_card=tcard, trump_color=tcolor, played_cards=the_game.played_cards, last_trick=the_game.last_trick)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										29
									
								
								views/js_cardgame.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								views/js_cardgame.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from app_instance import api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@api.route("/js-cardgame/{file}")
 | 
				
			||||||
 | 
					def css(req, resp, file):
 | 
				
			||||||
 | 
					    resp.headers['Content-Type'] = 'application/javascript'
 | 
				
			||||||
 | 
					    full_file = os.path.join(
 | 
				
			||||||
 | 
					        os.path.dirname(__file__),
 | 
				
			||||||
 | 
					        '..',
 | 
				
			||||||
 | 
					        'js-cardgame',
 | 
				
			||||||
 | 
					        file
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    with open(full_file, encoding='utf-8') as fin:
 | 
				
			||||||
 | 
					        resp.content = fin.read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@api.route("/js-cardgame/js/{file}")
 | 
				
			||||||
 | 
					def css(req, resp, file):
 | 
				
			||||||
 | 
					    resp.headers['Content-Type'] = 'application/javascript'
 | 
				
			||||||
 | 
					    full_file = os.path.join(
 | 
				
			||||||
 | 
					        os.path.dirname(__file__),
 | 
				
			||||||
 | 
					        '..',
 | 
				
			||||||
 | 
					        'js-cardgame',
 | 
				
			||||||
 | 
					        'js',
 | 
				
			||||||
 | 
					        file
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    with open(full_file, encoding='utf-8') as fin:
 | 
				
			||||||
 | 
					        resp.content = fin.read()
 | 
				
			||||||
		Reference in New Issue
	
	Block a user