<commit_before>{% extends 'author/layout.twig' %}

{% block body %}

    <div class="js-file-challenge-wrapper activity-wrapper">
        <div class="pull-right">
            <button class="btn btn-xs btn-link js-show-file-list">Change File</button>
            <ul class="js-file-list" style="display: none;">
                {% for file in otherFiles %}
                    <li>
                        <a href="{{ activityUrl }}?path={{ file.fullPath }}">{{ file.shortPath }}</a>
                    </li>
                {% endfor %}
            </ul>
        </div>

        <h3>
            {{ challenge.question }}
        </h3>

        <div class="js-result alert">
        </div>

        <div class="row">
            <div class="col-xs-8">
                <ul class="nav nav-tabs nav-tabs-dark">
                    {% for file in fileBuilder.allFiles %}
                        <li role="presentation" class="{{ loop.first ? 'active' }}">
                            <a href="#editor-{{ loop.index }}">{{ file.filename }}</a>
                        </li>
                    {% endfor %}
                </ul>

                <div class="js-input-files tab-content">
                    {% for file in fileBuilder.allFiles %}
                        <div role="tabpanel"
                             class="tab-pane {{ loop.first ? 'active' }}"
                             id="editor-{{ loop.index }}">

                            <textarea name="{{ file.filename }}"
                                  class="js-file form-control">{{ file.contents }}</textarea>
                        </div>
                    {% endfor %}
                </div>
            </div>
            <div class="col-xs-4">
                <ul class="nav nav-tabs nav-tabs-dark">
                    <li role="presentation" class="active">
                        <a href="#">Output</a>
                    </li>
                </ul>
                <iframe src="about:blank" frameborder="0" class="js-output"></iframe>
            </div>
        </div>

        <button class="btn btn-primary js-button-grade">Grade</button>

        <div>
            <h4>Correct Answer</h4>
            <a href="#" class="js-toggle-correct-answer">Toggle Correct Answer</a>
            |
            <a href="#" class="js-copy-correct-answers">Copy correct answers up</a>
            <div class="js-correct-answer-wrapper" style="display: none;">
                {% for file in correctAnswer.files %}
                    <div>
                        <h3>{{ file.filename }}</h3>
                        <textarea name="{{ file.filename }}"
                                  class="form-control js-file">{{ file.contents }}</textarea>
                    </div>
                {% endfor %}
            </div>
        </div>
    </div>
{% endblock %}

{% block javascripts %}
    {{ parent() }}

    <script>
        var ChallengeApp = function($wrapper) {
            this.initialize($wrapper);
        };

        $.extend(ChallengeApp.prototype, {
            $wrapper: null,

            initialize: function($wrapper) {
                this.$wrapper = $wrapper;

                this.$wrapper.on(
                    'click',
                    '.js-button-grade',
                    $.proxy(this._handleGradeClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.js-toggle-correct-answer',
                    $.proxy(this._handleToggleCorrectClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.js-copy-correct-answers',
                    $.proxy(this.handleCopyCorrectAnswersClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.nav-tabs a',
                    $.proxy(this._handleFileTabClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.js-show-file-list',
                    $.proxy(this._handleShowFileListClick, this)
                );
            },

            grade: function() {
                var gradingData = {
                    files: {},
                    path: '{{ path }}'
                };
                this.$wrapper.find('.js-input-files .js-file').each(function() {
                    gradingData.files[$(this).attr('name')] = $(this).val();
                });

                var self = this;
                $.ajax({
                    url: '{{ gradingUrl }}',
                    method: 'POST',
                    data: gradingData,
                    success: function(data) {
                        self.printGradingResponse(data);
                    }
                });
            },

            printGradingResponse: function(data) {
                var $result = this.$wrapper.find('.js-result');

                if (data.isCorrect) {
                    $result.html('<h3>CORRECT!</h3>');
                    $result.removeClass('alert-danger')
                        .addClass('alert-success');
                } else {
                    if (data.errors.validation) {
                        $result.html(data.errors.validation);
                    } else {
                        $result.html(data.errors.language)
                    }
                    $result.addClass('alert-danger')
                        .removeClass('alert-success');
                }

                var $iframe = this.$wrapper.find('.js-output');
                $iframe.contents().find('body').html(data.output);
            },

            _handleGradeClick: function(e) {
                e.preventDefault();

                this.grade();
            },

            _handleToggleCorrectClick: function(e) {
                e.preventDefault();

                this.$wrapper.find('.js-correct-answer-wrapper').toggle();
            },

            handleCopyCorrectAnswersClick: function(e) {
                e.preventDefault();

                // loop over the correct answers
                var $invalidAnswerWrapper = this.$wrapper.find('.js-input-files');
                this.$wrapper.find('.js-correct-answer-wrapper .js-file').each(function() {
                    // find the same file and copy the contents up
                    $invalidAnswerWrapper.find('[name="'+$(this).attr('name')+'"]')
                        .val($(this).val());
                });
            },

            _handleFileTabClick: function(e) {
                e.preventDefault();

                var $tab = $(e.currentTarget);
                $tab.tab('show');
            },

            _handleShowFileListClick: function(e) {
                e.preventDefault();

                this.$wrapper.find('.js-file-list').slideToggle();
            }
        });

        jQuery(document).ready(function() {
            var $wrapper = $('.js-file-challenge-wrapper');

            var challengeApp = new ChallengeApp($wrapper);
        });
    </script>
{% endblock %}

<commit_msg>Output lock icon for read-only files with a short notice<commit_after>{% extends 'author/layout.twig' %}

{% block body %}

    <div class="js-file-challenge-wrapper activity-wrapper">
        <div class="pull-right">
            <button class="btn btn-xs btn-link js-show-file-list">Change File</button>
            <ul class="js-file-list" style="display: none;">
                {% for file in otherFiles %}
                    <li>
                        <a href="{{ activityUrl }}?path={{ file.fullPath }}">{{ file.shortPath }}</a>
                    </li>
                {% endfor %}
            </ul>
        </div>

        <h3>
            {{ challenge.question }}
        </h3>

        <div class="js-result alert">
        </div>

        <div class="row">
            <div class="col-xs-8">
                <ul class="nav nav-tabs nav-tabs-dark">
                    {% for file in fileBuilder.allFiles %}
                        <li role="presentation" class="{{ loop.first ? 'active' }}">
                            <a href="#editor-{{ loop.index }}">
                                {% if file.readonly %}
                                    <span title="This file is in the read only mode">&#128274;</span>
                                {% endif %}
                                {{ file.filename }}
                            </a>
                        </li>
                    {% endfor %}
                </ul>

                <div class="js-input-files tab-content">
                    {% for file in fileBuilder.allFiles %}
                        <div role="tabpanel"
                             class="tab-pane {{ loop.first ? 'active' }}"
                             id="editor-{{ loop.index }}">

                            <textarea name="{{ file.filename }}"
                                      class="js-file form-control"
                                      {% if file.readonly %}readonly{% endif %}
                            >{{ file.contents }}</textarea>
                        </div>
                    {% endfor %}
                </div>
            </div>
            <div class="col-xs-4">
                <ul class="nav nav-tabs nav-tabs-dark">
                    <li role="presentation" class="active">
                        <a href="#">Output</a>
                    </li>
                </ul>
                <iframe src="about:blank" frameborder="0" class="js-output"></iframe>
            </div>
        </div>

        <button class="btn btn-primary js-button-grade">Grade</button>

        <div>
            <h4>Correct Answer</h4>
            <a href="#" class="js-toggle-correct-answer">Toggle Correct Answer</a>
            |
            <a href="#" class="js-copy-correct-answers">Copy correct answers up</a>
            <div class="js-correct-answer-wrapper" style="display: none;">
                {% for file in correctAnswer.files %}
                    <div>
                        <h3>{{ file.filename }}</h3>
                        <textarea name="{{ file.filename }}"
                                  class="form-control js-file">{{ file.contents }}</textarea>
                    </div>
                {% endfor %}
            </div>
        </div>
    </div>
{% endblock %}

{% block javascripts %}
    {{ parent() }}

    <script>
        var ChallengeApp = function($wrapper) {
            this.initialize($wrapper);
        };

        $.extend(ChallengeApp.prototype, {
            $wrapper: null,

            initialize: function($wrapper) {
                this.$wrapper = $wrapper;

                this.$wrapper.on(
                    'click',
                    '.js-button-grade',
                    $.proxy(this._handleGradeClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.js-toggle-correct-answer',
                    $.proxy(this._handleToggleCorrectClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.js-copy-correct-answers',
                    $.proxy(this.handleCopyCorrectAnswersClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.nav-tabs a',
                    $.proxy(this._handleFileTabClick, this)
                );

                this.$wrapper.on(
                    'click',
                    '.js-show-file-list',
                    $.proxy(this._handleShowFileListClick, this)
                );
            },

            grade: function() {
                var gradingData = {
                    files: {},
                    path: '{{ path }}'
                };
                this.$wrapper.find('.js-input-files .js-file').each(function() {
                    gradingData.files[$(this).attr('name')] = $(this).val();
                });

                var self = this;
                $.ajax({
                    url: '{{ gradingUrl }}',
                    method: 'POST',
                    data: gradingData,
                    success: function(data) {
                        self.printGradingResponse(data);
                    }
                });
            },

            printGradingResponse: function(data) {
                var $result = this.$wrapper.find('.js-result');

                if (data.isCorrect) {
                    $result.html('<h3>CORRECT!</h3>');
                    $result.removeClass('alert-danger')
                        .addClass('alert-success');
                } else {
                    if (data.errors.validation) {
                        $result.html(data.errors.validation);
                    } else {
                        $result.html(data.errors.language)
                    }
                    $result.addClass('alert-danger')
                        .removeClass('alert-success');
                }

                var $iframe = this.$wrapper.find('.js-output');
                $iframe.contents().find('body').html(data.output);
            },

            _handleGradeClick: function(e) {
                e.preventDefault();

                this.grade();
            },

            _handleToggleCorrectClick: function(e) {
                e.preventDefault();

                this.$wrapper.find('.js-correct-answer-wrapper').toggle();
            },

            handleCopyCorrectAnswersClick: function(e) {
                e.preventDefault();

                // loop over the correct answers
                var $invalidAnswerWrapper = this.$wrapper.find('.js-input-files');
                this.$wrapper.find('.js-correct-answer-wrapper .js-file').each(function() {
                    // find the same file and copy the contents up
                    $invalidAnswerWrapper.find('[name="'+$(this).attr('name')+'"]')
                        .val($(this).val());
                });
            },

            _handleFileTabClick: function(e) {
                e.preventDefault();

                var $tab = $(e.currentTarget);
                $tab.tab('show');
            },

            _handleShowFileListClick: function(e) {
                e.preventDefault();

                this.$wrapper.find('.js-file-list').slideToggle();
            }
        });

        jQuery(document).ready(function() {
            var $wrapper = $('.js-file-challenge-wrapper');

            var challengeApp = new ChallengeApp($wrapper);
        });
    </script>
{% endblock %}


{'fraction_non_alphanumeric': 0.14029543112332532, 'fraction_numerical': 0.0019237375472346272, 'mean_word_length': 1.0904782421370098, 'pattern_counts': {'":': 0, '<': 133, '<?xml version=': 0, '>': 133, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6633044', 'n_tokens_mistral': 3822, 'n_tokens_neox': 3397, 'n_words': 615}