Exemple #1
0
def initialize(bind=None, auth=None):
    global ENV
    if ENV is None:
        ENV = Environment(bind=bind)
        ENV.start()
        gevent.spawn(ENV.discover, 10)
    if auth is not None:
        elems = auth.split(':', 1)
        username = elems[0]
        password = elems[1]
        print("Protected server with basic auth username/password: ", username, password)
        app.config['BASIC_AUTH_USERNAME'] = username
        app.config['BASIC_AUTH_PASSWORD'] = password
        app.config['BASIC_AUTH_FORCE'] = True
        basic_auth = BasicAuth(app)
    def setUp(self):
        app = Flask(__name__)

        app.config['BASIC_AUTH_USERNAME'] = '******'
        app.config['BASIC_AUTH_PASSWORD'] = '******'

        basic_auth = BasicAuth(app)

        @app.route('/')
        def normal_view():
            return 'This view does not normally require authentication.'

        @app.route('/protected')
        @basic_auth.required
        def protected_view():
            return 'This view always requires authentication.'

        self.app = app
        self.basic_auth = basic_auth
        self.client = app.test_client()
Exemple #3
0
def make_app():
    app = sandman2.get_app(config.SQLA_URI, Base=utils.AutomapModel)
    app.json_encoder = utils.APIJSONEncoder
    app.config['CASE_INSENSITIVE'] = config.CASE_INSENSITIVE
    app.config['BASIC_AUTH_USERNAME'] = os.environ.get('AUTOAPI_ADMIN_USERNAME', '')
    app.config['BASIC_AUTH_PASSWORD'] = os.environ.get('AUTOAPI_ADMIN_PASSWORD', '')

    CORS(app)
    basic_auth = BasicAuth(app)

    @app.before_request
    def refresh():
        tables = utils.get_tables()
        if tables != app.config['SQLALCHEMY_TABLES']:
            utils.refresh_tables()
            app.config['SQLALCHEMY_TABLES'] = tables

    @app.before_request
    def protect_admin():
        if request.path.startswith('/admin/'):
            if not basic_auth.authenticate():
                return basic_auth.challenge()

    aws_blueprint = aws.make_blueprint()
    app.register_blueprint(aws_blueprint)

    docs_blueprint = swagger.make_blueprint(app)
    app.register_blueprint(docs_blueprint)

    route = os.path.join('/api-program', config.API_NAME)
    container = DispatcherMiddleware(app.wsgi_app, {route: app})

    with app.app_context():
        app.config['SQLALCHEMY_TABLES'] = utils.get_tables()
        utils.activate()

    return app, container
kv_store = KVSessionExtension(store, app)

Health(app, checks=[db.health])

# Audit, error handling and after_request headers all handled by lrutils
Audit(app)
ErrorHandler(app)
app.after_request(eh_after_request)

if not app.debug:
    app.logger.addHandler(logging.StreamHandler())
    app.logger.setLevel(logging.INFO)

if app.config.get('BASIC_AUTH_USERNAME'):
    app.config['BASIC_AUTH_FORCE'] = True
    basic_auth = BasicAuth(app)

# Sentry exception reporting
if 'SENTRY_DSN' in os.environ:
    sentry = Sentry(app, dsn=os.environ['SENTRY_DSN'])

app.logger.debug("\nConfiguration\n%s\n" % app.config)

# import and register auth blueprint
from .auth.views import auth
app.register_blueprint(auth)
login_manager.login_view = 'auth.login'
login_manager.login_message = ''

from .relationship.views import relationship
app.register_blueprint(relationship)
Exemple #5
0
def create_app(config=None): #pylint: disable=too-many-statements
    '''
    Create an instance of the app.
    '''
    app = Flask(__name__)

    with open('/noi/app/config/config.yml', 'r') as config_file:
        app.config.update(yaml.load(config_file))

    app.config['CELERYBEAT_SCHEDULE'] = CELERYBEAT_SCHEDULE

    if config is None:
        try:
            with open('/noi/app/config/local_config.yml', 'r') as config_file:
                app.config.update(yaml.load(config_file))
        except IOError:
            app.logger.warn("No local_config.yml file")
    else:
        app.config.update(config)

    # Confirming email is currently unsupported.
    app.config['SECURITY_CONFIRMABLE'] = False

    with open('/noi/app/data/deployments.yaml') as deployments_yaml:
        deployments = yaml.load(deployments_yaml)

    l10n.configure_app(app)

    app.register_blueprint(views)
    if app.config['DEBUG']:
        app.register_blueprint(style_guide.views)

        try:
            from flask_debugtoolbar import DebugToolbarExtension
            debug_toolbar = DebugToolbarExtension(app)
        except:
            app.logger.exception('Initialization of Flask-DebugToolbar '
                                 'failed.')

    if not app.config['DEBUG'] and app.config.get('ADMINS'):
        email_errors.init_app(app)

    cache.init_app(app)
    csrf.init_app(app)
    mail.init_app(app)
    bcrypt.init_app(app)
    s3.init_app(app)
    #configure_uploads(app, (photos))

    # Setup Flask-Security
    user_datastore = DeploySQLAlchemyUserDatastore(db, User, Role)
    security.init_app(app, datastore=user_datastore,
                      login_form=NOILoginForm,
                      register_form=NOIRegisterForm,
                      forgot_password_form=NOIForgotPasswordForm,
                      reset_password_form=NOIResetPasswordForm,
                      change_password_form=NOIChangePasswordForm)

    db.init_app(app)
    alchemydumps.init_app(app, db)
    #login_manager.init_app(app)
    assets.init_app(app)

    app.jinja_env.filters['slug'] = lambda x: slugify(x).lower()

    noi_deploy = app.config['NOI_DEPLOY']
    if noi_deploy == '_default':
        app.logger.warn('No NOI_DEPLOY found in config, deploy-specific '
                        'attributes like the About page, custom domains and '
                        'logos will be missing.')
    this_deployment = deployments.get(noi_deploy, deployments['_default'])
    default_deployment = deployments['_default']
    if 'locale' in this_deployment:
        app.config['BABEL_DEFAULT_LOCALE'] = this_deployment['locale']
    app.config['SEARCH_DEPLOYMENTS'] = this_deployment.get('searches', []) or []
    app.config['SEARCH_DEPLOYMENTS'].append(noi_deploy)
    babel.init_app(app)
    l10n.init_app(app)
    admin.init_app(app)

    app.config['DOMAINS'] = this_deployment.get('domains',
                                                default_deployment['domains'])

    app.config['CONTACT_FORM_ID'] = this_deployment.get('contact_form_id',
                                                default_deployment['contact_form_id'])

    # Constants that should be available for all templates.

    global_config_json = {}

    for exposed_var in EXPOSED_APP_CONFIG_VARS:
        if exposed_var in app.config:
            global_config_json[exposed_var] = app.config[exposed_var]

    global_config_json = json.dumps(global_config_json)

    app.jinja_env.globals['global_config_json'] = global_config_json
    app.jinja_env.globals['get_locale'] = get_locale
    app.jinja_env.globals['NOI_DEPLOY'] = noi_deploy
    app.jinja_env.globals['ORG_TYPES'] = ORG_TYPES
    app.jinja_env.globals['NOI_COLORS'] = NOI_COLORS
    app.jinja_env.globals['LEVELS'] = LEVELS
    app.jinja_env.globals['LEVELS_BY_SCORE'] = LEVELS_BY_SCORE
    app.jinja_env.globals['QUESTIONS_BY_ID'] = QUESTIONS_BY_ID
    app.jinja_env.globals['QUESTIONNAIRES_BY_ID'] = QUESTIONNAIRES_BY_ID

    app.jinja_env.globals['ABOUT'] = this_deployment.get('about',
                                                         default_deployment['about'])

    if not app.config.get('MAIL_USERNAME') or not app.config.get('MAIL_PASSWORD'):
        app.logger.warn('No MAIL_SERVER found in config, password reset will '
                        'not work.')

    if not app.config.get('GA_TRACKING_CODE'):
        app.logger.warn('No GA_TRACKING_CODE found in config, analytics will'
                        ' not work.')

    # Order questionnaires for deployments that want custom order.
    questionnaire_order = this_deployment.get('questions',
                                              default_deployment['questions'])
    if questionnaire_order:
        new_order = []
        for topic in questionnaire_order:
            if isinstance(topic, basestring):
                q_id = topic
                custom_description = None
            else:
                q_id = topic.keys()[0]
                custom_description = topic[q_id].get('description')

            try:
                questionnaire = [q for q in QUESTIONNAIRES if q['id'] == q_id][0]
                if custom_description:
                    questionnaire['description'] = custom_description
                new_order.append(questionnaire)
                #new_order.append(filter(lambda q: q['id'] == q_id, QUESTIONNAIRES)[0])
            except IndexError:
                raise Exception('Cannot find questionairre ID "{}", aborting'.format(
                    q_id))
        app.jinja_env.globals['QUESTIONNAIRES'] = new_order
    else:
        app.jinja_env.globals['QUESTIONNAIRES'] = QUESTIONNAIRES

    # Signals
    @user_registered.connect_via(app)
    def add_deployment_role(sender, **kwargs):
        """
        Add role for this deployment whenever a new user registers.
        """
        user = kwargs['user']
        try:
            role = Role.query.filter_by(name=sender.config['NOI_DEPLOY']).one()
        except NoResultFound:
            role = Role(name=sender.config['NOI_DEPLOY'])
            db.session.add(role)

        user.roles.append(role)
        db.session.add(user)
        db.session.commit()

    sass.init_app(app)
    csp.init_app(app)

    if app.config.get('BASIC_AUTH_FORCE'):
        from flask.ext.basicauth import BasicAuth

        basic_auth = BasicAuth()
        basic_auth.init_app(app)

    return app
Exemple #6
0
def init_basic_auth():
    if not app.config.get('NO_AUTH'):
        basic_auth = BasicAuth(app)
Exemple #7
0
command = MJPG_STREAMER_PATH + ' -i \"' + INPUT_PATH + '" -o "' + OUTPUT_PATH + '" &'
print command
os.system(command)  #Run mjpg streamer

FILE_CONFIG = "/var/www/Raspbrr/config"  #Config file location
offset = "0"
offset_x = "0"
offset_y = "0"
forward0 = "True"
forward1 = "True"

app.config['BASIC_AUTH_USERNAME'] = '******'
app.config['BASIC_AUTH_PASSWORD'] = '******'
app.config['BASIC_AUTH_FORCE'] = True  #Force authenication for every page

basic_auth = BasicAuth(app)  #Use Basic Authenication

for line in open(FILE_CONFIG):
    if line[0:8] == 'offset_x':
        offset_x = int(line[11:-1])
    if line[0:8] == 'offset_y':
        offset_y = int(line[11:-1])
    if line[0:8] == 'offset =':
        offset = int(line[9:-1])
    if line[0:8] == "forward0":
        forward0 = line[11:-1]
    if line[0:8] == "forward1":
        forward1 = line[11:-1]

import drivers  #Added drivers script
Exemple #8
0
from MALMan import app
import MALMan.database as DB

from flask import Response, request
from flask_security.utils import verify_and_update_password
from flask.ext.basicauth import BasicAuth

import json
from datetime import datetime

api_auth = BasicAuth(app)


@app.route("/api/stock")
@api_auth.required
def list_stock():
    stock = DB.StockItem.query.filter_by(active=True).all()
    items = [{
        'id': str(item.id),
        'name': str(item.name),
        'price': str(item.price),
        'category': str(item.category.name)
    } for item in stock]
    return Response(json.dumps(items), mimetype='application/json')


@app.route("/api/user")
@api_auth.required
def list_users():
    minimalprice = DB.StockItem.query.order_by(DB.StockItem.price).first()
    users = DB.User.query.order_by(DB.User.name).all()
Exemple #9
0
from ncsdaemon.services.user import UserService

# Create new application
app = Flask(__name__)

# set app route
app.config['APPLICATION_ROUTE'] = '/ncs/api'

# enforce basic authentication on all endpoints
app.config['BASIC_AUTH_FORCE'] = True

# restful api
api = Api(app)

# we use HTTP basic auth here
basic_auth = BasicAuth(app)
# tell BasicAuth how to authenticate our user
basic_auth.check_credentials = UserService.authenticate

# allow us to use UUID's in routes
FlaskUUID(app)

# add resources
api.add_resource(SimulatorResource, '/simulator')
api.add_resource(SimulationResource, '/simulation/<uuid:sim_id>')
api.add_resource(ReportResource, '/report/<uuid:report_id>')


@click.command()
@click.option("--host", default="0.0.0.0", help="Host to bind to.")
@click.option("--port", default=6767, help="Port to bind to.")
Exemple #10
0
def create_app(config=None):  #pylint: disable=too-many-statements
    '''
    Create an instance of the app.
    '''
    app = Flask(__name__)

    with open('/noi/app/config/config.yml', 'r') as config_file:
        app.config.update(yaml.load(config_file))

    if config is None:
        try:
            with open('/noi/app/config/local_config.yml', 'r') as config_file:
                app.config.update(yaml.load(config_file))
        except IOError:
            app.logger.warn("No local_config.yml file")
        configure_from_os_environment(app.config)
    else:
        app.config.update(config)

    # Confirming email is currently unsupported.
    app.config['SECURITY_CONFIRMABLE'] = False

    with open('/noi/app/data/deployments.yaml') as deployments_yaml:
        deployments = yaml.load(deployments_yaml)

    l10n.configure_app(app)

    app.register_blueprint(views)
    if app.config['DEBUG']:
        app.register_blueprint(style_guide.views)

        try:
            from flask_debugtoolbar import DebugToolbarExtension
            debug_toolbar = DebugToolbarExtension(app)
        except:
            app.logger.exception('Initialization of Flask-DebugToolbar '
                                 'failed.')

    if not app.config['DEBUG'] and app.config.get('ADMINS'):
        email_errors.init_app(app)

    oauth.init_app(app)
    if 'LINKEDIN' in app.config:
        app.jinja_env.globals['LINKEDIN_ENABLED'] = True
        app.register_blueprint(linkedin.views)

    cache.init_app(app)
    csrf.init_app(app)
    mail.init_app(app)
    bcrypt.init_app(app)
    s3.init_app(app)

    # Setup Flask-Security
    user_datastore = DeploySQLAlchemyUserDatastore(db, User, Role)
    security.init_app(app,
                      datastore=user_datastore,
                      login_form=NOILoginForm,
                      register_form=NOIRegisterForm,
                      forgot_password_form=NOIForgotPasswordForm,
                      reset_password_form=NOIResetPasswordForm,
                      change_password_form=NOIChangePasswordForm)

    db.init_app(app)
    alchemydumps.init_app(app, db)
    #login_manager.init_app(app)
    assets.init_app(app)

    app.jinja_env.filters['slug'] = lambda x: slugify(x).lower()

    noi_deploy = app.config['NOI_DEPLOY']
    if noi_deploy == '_default':
        app.logger.warn('No NOI_DEPLOY found in config, deploy-specific '
                        'attributes like the About page, custom domains and '
                        'logos will be missing.')
    this_deployment = deployments.get(noi_deploy, deployments['_default'])
    default_deployment = deployments['_default']
    if 'locale' in this_deployment:
        app.config['BABEL_DEFAULT_LOCALE'] = this_deployment['locale']
    app.config['SEARCH_DEPLOYMENTS'] = this_deployment.get('searches',
                                                           []) or []
    app.config['SEARCH_DEPLOYMENTS'].append(noi_deploy)
    babel.init_app(app)
    l10n.init_app(app)
    admin.init_app(app)

    app.config['DOMAINS'] = this_deployment.get('domains',
                                                default_deployment['domains'])

    app.config['CONTACT_FORM_ID'] = this_deployment.get(
        'contact_form_id', default_deployment['contact_form_id'])

    # Constants that should be available for all templates.

    global_config_json = {}

    for exposed_var in EXPOSED_APP_CONFIG_VARS:
        if exposed_var in app.config:
            global_config_json[exposed_var] = app.config[exposed_var]

    global_config_json = json.dumps(global_config_json)

    app.jinja_env.globals['global_config_json'] = global_config_json
    app.jinja_env.globals['get_locale'] = get_locale
    app.jinja_env.globals['get_nopic_avatar'] = get_nopic_avatar
    app.jinja_env.globals['NOI_DEPLOY'] = noi_deploy
    app.jinja_env.globals['ORG_TYPES'] = ORG_TYPES
    app.jinja_env.globals['NOI_COLORS'] = NOI_COLORS
    app.jinja_env.globals['LEVELS'] = LEVELS
    app.jinja_env.globals['LEVELS_BY_SCORE'] = LEVELS_BY_SCORE
    app.jinja_env.globals['QUESTIONS_BY_ID'] = QUESTIONS_BY_ID
    app.jinja_env.globals['QUESTIONNAIRES_BY_ID'] = QUESTIONNAIRES_BY_ID

    app.jinja_env.globals['ABOUT'] = this_deployment.get(
        'about', default_deployment['about'])

    if not app.config.get('MAIL_SERVER'):
        app.logger.warn('No MAIL_SERVER found in config, password reset will '
                        'not work.')

    if not app.config.get('GA_TRACKING_CODE'):
        app.logger.warn('No GA_TRACKING_CODE found in config, analytics will'
                        ' not work.')

    # Order questionnaires for deployments that want custom order.
    questionnaire_order = this_deployment.get('questions',
                                              default_deployment['questions'])
    if questionnaire_order:
        new_order = []
        for topic in questionnaire_order:
            if isinstance(topic, basestring):
                q_id = topic
                custom_description = None
            else:
                q_id = topic.keys()[0]
                custom_description = topic[q_id].get('description')

            try:
                questionnaire = [q for q in QUESTIONNAIRES
                                 if q['id'] == q_id][0]
                if custom_description:
                    questionnaire['description'] = custom_description
                new_order.append(questionnaire)
                #new_order.append(filter(lambda q: q['id'] == q_id, QUESTIONNAIRES)[0])
            except IndexError:
                raise Exception(
                    'Cannot find questionairre ID "{}", aborting'.format(q_id))
        app.jinja_env.globals['QUESTIONNAIRES'] = new_order
    else:
        app.jinja_env.globals['QUESTIONNAIRES'] = QUESTIONNAIRES

    # Signals
    @user_registered.connect_via(app)
    def add_deployment_role(sender, **kwargs):
        """
        Add role for this deployment whenever a new user registers.
        """
        user = kwargs['user']
        try:
            role = Role.query.filter_by(name=sender.config['NOI_DEPLOY']).one()
        except NoResultFound:
            role = Role(name=sender.config['NOI_DEPLOY'])
            db.session.add(role)

        user.roles.append(role)
        db.session.add(user)
        db.session.commit()

    sass.init_app(app)
    csp.init_app(app)

    if app.config.get('BASIC_AUTH_FORCE'):
        from flask.ext.basicauth import BasicAuth

        basic_auth = BasicAuth()
        basic_auth.init_app(app)

    app.wsgi_app = ProxyFix(app.wsgi_app)

    return app
Exemple #11
0
def make_app():
    app = sandman2.get_app(config.SQLA_URI, Base=utils.AutomapModel)

    app.json_encoder = utils.APIJSONEncoder
    app.config['CASE_INSENSITIVE'] = config.CASE_INSENSITIVE
    app.config['BASIC_AUTH_USERNAME'] = os.environ.get(
        'AUTOAPI_ADMIN_USERNAME', '')
    app.config['BASIC_AUTH_PASSWORD'] = os.environ.get(
        'AUTOAPI_ADMIN_PASSWORD', '')

    CORS(app)
    basic_auth = BasicAuth(app)

    @app.before_request
    def refresh():
        tables = utils.get_tables()
        if tables != app.config['SQLALCHEMY_TABLES']:
            utils.refresh_tables()
            app.config['SQLALCHEMY_TABLES'] = tables

    @app.before_request
    def protect_admin():
        if request.path.startswith('/admin/'):
            if not basic_auth.authenticate():
                return basic_auth.challenge()

    class RefreshTables(View):

        task_name = 'refresh'

        def dispatch_request(self):
            underway = RefreshLog.refresh_underway()
            if underway:
                return '''Refresh begun at {} still underway.

                Now: {}; timeout set for {} seconds'''.format(
                    underway.begun_at, datetime.now(),
                    config.REFRESH_TIMEOUT_SECONDS)
            try:
                subprocess.Popen([
                    'invoke',
                    self.task_name,
                ])
            except Exception as e:
                print('Problem with table refresh:')
                print(e)
            return 'Table refresh requested.'

    class QuickRefreshTables(RefreshTables):

        task_name = 'quick_refresh'

    app.add_url_rule('/refresh/', view_func=RefreshTables.as_view('refresh'))
    app.add_url_rule('/quick_refresh/',
                     view_func=QuickRefreshTables.as_view('quick_refresh'))

    aws_blueprint = aws.make_blueprint()
    app.register_blueprint(aws_blueprint)

    docs_blueprint = swagger.make_blueprint(app)
    app.register_blueprint(docs_blueprint)

    with app.app_context():
        app.config['SQLALCHEMY_TABLES'] = utils.get_tables()
        utils.activate()

    refresh_log_db.init_app(app)
    refresh_log_db.create_all(app=app)

    return app
Exemple #12
0
def main():
    parser = cli_parser()
    args = parser.parse_args()

    debug_smqtk = args.debug_smqtk
    debug_server = args.debug_server

    bin_utils.initialize_logging(logging.getLogger("smqtk"),
                                 logging.INFO - (10 * debug_smqtk))
    bin_utils.initialize_logging(logging.getLogger("werkzeug"),
                                 logging.WARN - (20 * debug_server))
    log = logging.getLogger("smqtk.main")

    web_applications = smqtk.web.get_web_applications()

    if args.list:
        log.info("")
        log.info("Available applications:")
        log.info("")
        for l in web_applications:
            log.info("\t" + l)
        log.info("")
        exit(0)

    application_name = args.application

    if application_name is None:
        log.error("No application name given!")
        exit(1)
    elif application_name not in web_applications:
        log.error("Invalid application label '%s'", application_name)
        exit(1)

    app_class = web_applications[application_name]

    # Merge loaded config with default
    config_loaded = False
    config = app_class.get_default_config()
    if args.config:
        if os.path.isfile(args.config):
            with open(args.config, 'r') as f:
                config.update(json.load(f))
            config_loaded = True
        elif not os.path.isfile(args.config):
            log.error("Configuration file path not valid.")
            exit(1)

    # Output config and exit if requested
    bin_utils.output_config(args.output_config, config, log, args.overwrite)

    # Configuration must have been loaded at this point since we can't normally
    # trust the default.
    if not config_loaded:
        log.error("No configuration provided")
        exit(1)

    host = args.host
    port = args.port and int(args.port)
    use_reloader = args.reload
    use_threading = args.threaded
    use_basic_auth = args.use_basic_auth

    # noinspection PyUnresolvedReferences
    app = app_class.from_config(config)
    if use_basic_auth:
        app.config["BASIC_AUTH_FORCE"] = True
        BasicAuth(app)
    app.config['DEBUG'] = debug_server

    app.run(host=host,
            port=port,
            debug=debug_server,
            use_reloader=use_reloader,
            threaded=use_threading)
Exemple #13
0
from flask import render_template, Blueprint, url_for, redirect, request
from flask.ext.basicauth import BasicAuth
from multiprocessing import Pool, Process
import requests
import pprint

from services_util import *
from services_discord import remove_roles

services_admin = Blueprint('services_admin', __name__)

basic_auth = BasicAuth()

#hack
@services_admin.record_once
def on_load(state):
  basic_auth.init_app(state.app)

@services_admin.route('/')
@basic_auth.required
def adminpage():
  """
  Method returns accounts with pending New/Delete status.
  """
  add_to_slack_query = query_db('SELECT name, email from pilots '
                                'WHERE keyid NOT NULL '
                                'AND vcode NOT NULL ' 
                                'AND slack_active=0 '
                                'AND active_account=1 '
                                'AND in_alliance=1')
  add_to_slack=""
Exemple #14
0
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.basicauth import BasicAuth
from config import APPLICATION_ID, REST_API_KEY, MASTER_KEY
from parse_rest.connection import register

app = Flask(__name__)
admin = Admin(app, template_mode='bootstrap3')

app.config.from_object('config')
app.config['BASIC_AUTH_FORCE'] = False
register(APPLICATION_ID, REST_API_KEY)

db = SQLAlchemy(app)

BasicAuth(app)

import apmcs.views, apmcs.models, apmcs.admin
from flask.ext.assets import Bundle, Environment

bundles = {
    'home_js':
    Bundle('js/jquery.min.js',
           'js/bootstrap.min.js',
           output='gen/home.js',
           filters='jsmin'),
    'home_css':
    Bundle('css/bootstrap.min.css',
           'css/bootstrap-theme.min.css',
           output='gen/home.css',
           filters='cssmin'),